diff --git a/src/API/Cachers/DefaultCacher.php b/src/API/Cachers/DefaultCacher.php index 05893b0acde..2679738ad83 100644 --- a/src/API/Cachers/DefaultCacher.php +++ b/src/API/Cachers/DefaultCacher.php @@ -15,7 +15,13 @@ class DefaultCacher extends AbstractCacher */ public function get(Request $request) { - return Cache::get($this->getCacheKey($request)); + $cached = Cache::get($this->getCacheKey($request)); + + if (! is_array($cached)) { + return null; + } + + return new JsonResponse($cached['content'], $cached['status'], $cached['headers'], json: true); } /** @@ -25,7 +31,11 @@ public function put(Request $request, JsonResponse $response) { $key = $this->trackEndpoint($request); - Cache::put($key, $response, $this->cacheExpiry()); + Cache::put($key, [ + 'content' => $response->getContent(), + 'status' => $response->getStatusCode(), + 'headers' => $response->headers->all(), + ], $this->cacheExpiry()); } /** diff --git a/src/GraphQL/ResponseCache/DefaultCache.php b/src/GraphQL/ResponseCache/DefaultCache.php index d49014bce31..14a99190933 100644 --- a/src/GraphQL/ResponseCache/DefaultCache.php +++ b/src/GraphQL/ResponseCache/DefaultCache.php @@ -2,6 +2,7 @@ namespace Statamic\GraphQL\ResponseCache; +use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use Illuminate\Support\Carbon; use Illuminate\Support\Facades\Cache; @@ -12,7 +13,13 @@ class DefaultCache implements ResponseCache { public function get(Request $request) { - return Cache::get($this->getCacheKey($request)); + $cached = Cache::get($this->getCacheKey($request)); + + if (! is_array($cached)) { + return null; + } + + return new JsonResponse($cached['content'], $cached['status'], $cached['headers'], json: true); } public function put(Request $request, $response) @@ -21,7 +28,11 @@ public function put(Request $request, $response) $ttl = Carbon::now()->addMinutes((int) config('statamic.graphql.cache.expiry', 60)); - Cache::put($key, $response, $ttl); + Cache::put($key, [ + 'content' => $response->getContent(), + 'status' => $response->getStatusCode(), + 'headers' => $response->headers->all(), + ], $ttl); } protected function track($request) diff --git a/src/Providers/AddonServiceProvider.php b/src/Providers/AddonServiceProvider.php index ef1f903ed93..aa827598bd0 100644 --- a/src/Providers/AddonServiceProvider.php +++ b/src/Providers/AddonServiceProvider.php @@ -721,14 +721,11 @@ protected function registerSerializableClasses(array $classes) { $existing = $this->app['config']->get('cache.serializable_classes'); - if ($existing === true) { + if ($existing === null || $existing === true) { return; } - $this->app['config']->set('cache.serializable_classes', array_merge( - is_array($existing) ? $existing : [], - $classes - )); + $this->app['config']->set('cache.serializable_classes', array_merge(is_array($existing) ? $existing : [], $classes)); } protected function schedule(Schedule $schedule) diff --git a/src/Providers/AppServiceProvider.php b/src/Providers/AppServiceProvider.php index 9ecdd2d5b5f..b8ac3fb8d48 100644 --- a/src/Providers/AppServiceProvider.php +++ b/src/Providers/AppServiceProvider.php @@ -239,12 +239,14 @@ private function registerSerializableClasses() { $existing = $this->app['config']->get('cache.serializable_classes'); - if ($existing === true) { + if ($existing === null || $existing === true) { return; } - $classes = [ + $this->app['config']->set('cache.serializable_classes', array_merge(is_array($existing) ? $existing : [], [ \Statamic\Auth\File\User::class, + \Statamic\Auth\File\Passkey::class, + \Statamic\Auth\Eloquent\Passkey::class, \Statamic\Assets\Asset::class, \Statamic\Assets\AssetContainer::class, \Statamic\Entries\Collection::class, @@ -264,12 +266,7 @@ private function registerSerializableClasses() \Carbon\Carbon::class, \Illuminate\Support\Carbon::class, \Illuminate\Support\Collection::class, - ]; - - $this->app['config']->set('cache.serializable_classes', array_merge( - is_array($existing) ? $existing : [], - $classes - )); + ])); } protected function registerMiddlewareGroup() diff --git a/tests/API/CacherTest.php b/tests/API/CacherTest.php index 7e8e227d59a..40fe3bfe7fd 100644 --- a/tests/API/CacherTest.php +++ b/tests/API/CacherTest.php @@ -57,7 +57,11 @@ public function it_caches_endpoint_using_default_cacher() $this->assertEquals([$cacheKey], Cache::get('api-cache:tracked-responses')); // manually manipulate whats in the cache so we can be sure it uses it. - Cache::put($cacheKey, response()->json(['foo' => 'bar']), 10); + Cache::put($cacheKey, [ + 'content' => json_encode(['foo' => 'bar']), + 'status' => 200, + 'headers' => ['content-type' => ['application/json']], + ], 10); $this->get($endpoint) ->assertOk() diff --git a/tests/Feature/GraphQL/RequestCacheTest.php b/tests/Feature/GraphQL/RequestCacheTest.php index e1fc9b72f76..97f6c2927ff 100644 --- a/tests/Feature/GraphQL/RequestCacheTest.php +++ b/tests/Feature/GraphQL/RequestCacheTest.php @@ -210,6 +210,23 @@ public function it_ignores_configured_events() ], $requests->all()); } + #[Test] + public function it_caches_response_data_as_primitives() + { + app()->instance('request-tracking', $requests = Collection::make()); + + $this->post('/graphql', ['query' => '{one}']); + + $key = 'gql-cache:'.md5('{one}').'_'.md5(json_encode(null)); + $cached = Cache::get($key); + + $this->assertIsArray($cached); + $this->assertArrayHasKey('content', $cached); + $this->assertArrayHasKey('status', $cached); + $this->assertArrayHasKey('headers', $cached); + $this->assertEquals(200, $cached['status']); + } + #[Test] public function it_can_disable_caching() {