diff --git a/src/Http/Middleware/CP/HandleAuthenticatedInertiaRequests.php b/src/Http/Middleware/CP/HandleAuthenticatedInertiaRequests.php index 1fc91378565..55cee2ec441 100644 --- a/src/Http/Middleware/CP/HandleAuthenticatedInertiaRequests.php +++ b/src/Http/Middleware/CP/HandleAuthenticatedInertiaRequests.php @@ -49,7 +49,7 @@ private function alwaysProps() return [ 'version' => Statamic::version(), 'isPro' => Statamic::pro(), - 'nav' => $this->nav(), + 'nav' => fn () => $this->nav(), 'cmsName' => __(Statamic::pro() ? config('statamic.cp.custom_cms_name', 'Statamic') : 'Statamic'), ]; } @@ -63,8 +63,8 @@ private function protectedProps() return [ 'supportUrl' => config('statamic.cp.support_url'), 'selectedSiteUrl' => Site::selected()->url(), - 'licensing' => $this->licensing(), - 'sessionExpiry' => $this->sessionExpiry(), + 'licensing' => fn () => $this->licensing(), + 'sessionExpiry' => fn () => $this->sessionExpiry(), ]; } diff --git a/src/Statamic.php b/src/Statamic.php index bd5d7149a32..619b95e10e8 100644 --- a/src/Statamic.php +++ b/src/Statamic.php @@ -512,13 +512,22 @@ public static function cpPerPage($perPage) public static function nonInertiaPageData() { - $props = Inertia::getShared(); - return [ 'url' => '/'.request()->path(), 'component' => 'NonInertiaPage', 'version' => inertia()->getVersion(), - 'props' => $props, + 'props' => static::resolveProps(Inertia::getShared()), ]; } + + private static function resolveProps(array $props) + { + return collect($props)->map(function ($value) { + if (is_object($value) && is_callable($value)) { + $value = App::call($value); + } + + return is_array($value) ? static::resolveProps($value) : $value; + })->all(); + } } diff --git a/tests/Http/Middleware/HandleAuthenticatedInertiaRequestsTest.php b/tests/Http/Middleware/HandleAuthenticatedInertiaRequestsTest.php new file mode 100644 index 00000000000..332ea190c2b --- /dev/null +++ b/tests/Http/Middleware/HandleAuthenticatedInertiaRequestsTest.php @@ -0,0 +1,103 @@ + ['foo' => 'bar']); + + Route::get('non-inertia-page-data-test', fn () => Statamic::nonInertiaPageData()); + }); + } + + #[Test] + public function it_doesnt_build_the_nav_for_responses_that_arent_inertia_pages() + { + $built = false; + + Nav::extend(function () use (&$built) { + $built = true; + }); + + $this + ->actingAs(User::make()->makeSuper()->save()) + ->get('/cp/json-response-test') + ->assertOk(); + + $this->assertFalse($built); + } + + #[Test] + public function it_builds_the_nav_for_inertia_pages() + { + $built = false; + + Nav::extend(function () use (&$built) { + $built = true; + }); + + $this + ->actingAs(User::make()->makeSuper()->save()) + ->get('/cp/dashboard') + ->assertOk(); + + $this->assertTrue($built); + } + + #[Test] + public function it_resolves_the_nav_for_pages_rendered_outside_of_inertia() + { + $data = $this + ->actingAs(User::make()->makeSuper()->save()) + ->get('/cp/non-inertia-page-data-test') + ->assertOk() + ->json(); + + $this->assertNotEmpty($data['props']['_statamic']['nav']); + } + + #[Test] + public function it_resolves_shared_callables_the_same_way_inertia_does() + { + Inertia::share([ + 'closure_with_dependency' => fn (Request $request) => $request->path(), + 'invokable' => new SharedInvokable, + ]); + + $data = $this + ->actingAs(User::make()->makeSuper()->save()) + ->get('/cp/non-inertia-page-data-test') + ->assertOk() + ->json(); + + $this->assertEquals('cp/non-inertia-page-data-test', $data['props']['closure_with_dependency']); + $this->assertEquals('invoked', $data['props']['invokable']); + } +} + +class SharedInvokable +{ + public function __invoke() + { + return 'invoked'; + } +}