Skip to content

Commit c50d1ad

Browse files
jasonvargaclaude
andauthored
[6.x] Serialize nocache regions before storing in cache (#14422)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 1b3c29d commit c50d1ad

3 files changed

Lines changed: 44 additions & 3 deletions

File tree

src/StaticCaching/NoCache/DatabaseSession.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public function region(string $key): Region
3030
throw new RegionNotFound($key);
3131
}
3232

33-
return unserialize($region->region);
33+
return unserialize($region->region, ['allowed_classes' => true]);
3434
}
3535

3636
protected function cacheRegion(Region $region)

src/StaticCaching/NoCache/Session.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,13 @@ public function regions(): Collection
5151
public function region(string $key): Region
5252
{
5353
if ($this->regions->contains($key) && ($region = StaticCache::cacheStore()->get('nocache::region.'.$key))) {
54-
return $region;
54+
if ($region instanceof Region) {
55+
return $region;
56+
}
57+
58+
if (is_string($region)) {
59+
return unserialize($region, ['allowed_classes' => true]);
60+
}
5561
}
5662

5763
throw new RegionNotFound($key);
@@ -150,6 +156,6 @@ protected function resolvePageAndPathForPagination(): void
150156

151157
protected function cacheRegion(Region $region)
152158
{
153-
StaticCache::cacheStore()->forever('nocache::region.'.$region->key(), $region);
159+
StaticCache::cacheStore()->forever('nocache::region.'.$region->key(), serialize($region));
154160
}
155161
}

tests/StaticCaching/NoCacheSessionTest.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
use Illuminate\Support\Facades\Cache;
77
use Mockery;
88
use PHPUnit\Framework\Attributes\Test;
9+
use Statamic\Facades\StaticCache;
910
use Statamic\StaticCaching\Cacher;
11+
use Statamic\StaticCaching\NoCache\RegionNotFound;
1012
use Statamic\StaticCaching\NoCache\Session;
1113
use Statamic\StaticCaching\NoCache\StringRegion;
1214
use Tests\FakesContent;
@@ -148,6 +150,39 @@ public function it_restores_from_cache()
148150
$this->assertEquals('http://localhost/cp', $cascade['cp_url']);
149151
}
150152

153+
#[Test]
154+
public function it_serializes_and_unserializes_regions_through_cache()
155+
{
156+
$session = new Session('http://localhost/test');
157+
158+
$region = $session->pushRegion('the contents', ['foo' => 'bar'], '.html');
159+
160+
$cached = StaticCache::cacheStore()->get('nocache::region.'.$region->key());
161+
$this->assertIsString($cached, 'Region should be stored as a serialized string, not an object.');
162+
163+
$retrieved = $session->region($region->key());
164+
165+
$this->assertInstanceOf(StringRegion::class, $retrieved);
166+
$this->assertEquals($region->key(), $retrieved->key());
167+
$this->assertEquals(['foo' => 'bar'], $retrieved->context());
168+
}
169+
170+
#[Test]
171+
public function it_throws_region_not_found_when_cached_region_is_an_incomplete_class()
172+
{
173+
$session = new Session('http://localhost/test');
174+
175+
$region = $session->pushRegion('the contents', ['foo' => 'bar'], '.html');
176+
177+
// Simulate what happens when serializable_classes enforcement
178+
// turns a cached Region object into __PHP_Incomplete_Class.
179+
StaticCache::cacheStore()->forever('nocache::region.'.$region->key(), new \__PHP_Incomplete_Class);
180+
181+
$this->expectException(RegionNotFound::class);
182+
183+
$session->region($region->key());
184+
}
185+
151186
#[Test]
152187
public function a_singleton_is_bound_in_the_container()
153188
{

0 commit comments

Comments
 (0)