diff --git a/src/Stache/Indexes/Index.php b/src/Stache/Indexes/Index.php index b4a6f3df6d0..db42a5233f6 100644 --- a/src/Stache/Indexes/Index.php +++ b/src/Stache/Indexes/Index.php @@ -11,7 +11,7 @@ abstract class Index protected $name; protected $items = []; protected $loaded = false; - private static ?string $currentlyLoading = null; + private static array $loadingStack = []; public function __construct($store, $name) { @@ -66,9 +66,9 @@ public function load() } $loadingKey = $this->store->key().'/'.$this->name; - $currentlyLoadingThis = static::$currentlyLoading === $loadingKey; + $currentlyLoadingThis = in_array($loadingKey, static::$loadingStack); - static::$currentlyLoading = $loadingKey; + static::$loadingStack[] = $loadingKey; $this->loaded = true; @@ -86,7 +86,7 @@ public function load() $this->store->cacheIndexUsage($this); - static::$currentlyLoading = null; + array_pop(static::$loadingStack); return $this; } @@ -163,6 +163,11 @@ public function clear() public static function currentlyLoading() { - return static::$currentlyLoading; + return end(static::$loadingStack) ?: null; + } + + public static function isLoading(): bool + { + return ! empty(static::$loadingStack); } } diff --git a/src/Stache/Stores/CollectionEntriesStore.php b/src/Stache/Stores/CollectionEntriesStore.php index f0bbcac96bc..71239162749 100644 --- a/src/Stache/Stores/CollectionEntriesStore.php +++ b/src/Stache/Stores/CollectionEntriesStore.php @@ -235,9 +235,7 @@ protected function getCachedItem($key) return null; } - $isLoadingIds = Index::currentlyLoading() === $this->key().'/id'; - - if (! $isLoadingIds && $this->shouldBlinkEntryUris && ($uri = $this->resolveIndex('uri')->load()->get($entry->id()))) { + if (! Index::isLoading() && $this->shouldBlinkEntryUris && ($uri = $this->resolveIndex('uri')->load()->get($entry->id()))) { Blink::store('entry-uris')->put($entry->id(), $uri); } diff --git a/src/Stache/Stores/Store.php b/src/Stache/Stores/Store.php index 9a20e58c73b..c220b679e1b 100644 --- a/src/Stache/Stores/Store.php +++ b/src/Stache/Stores/Store.php @@ -328,6 +328,8 @@ public function paths() return $isDuplicate ?? false; }); + $items->each(fn ($item) => $this->cacheItem($item['item'])); + $paths = $items->pluck('path', 'key'); $this->cachePaths($paths); diff --git a/tests/Stache/ColdStacheUriTest.php b/tests/Stache/ColdStacheUriTest.php new file mode 100644 index 00000000000..de0c8af31fd --- /dev/null +++ b/tests/Stache/ColdStacheUriTest.php @@ -0,0 +1,78 @@ +routes('{parent_uri}/{slug}') + ->structureContents(['root' => true]); + $collection->save(); + + EntryFactory::id('alfa-id')->collection('pages')->slug('alfa')->data(['title' => 'Alfa'])->create(); + EntryFactory::id('bravo-id')->collection('pages')->slug('bravo')->data(['title' => 'Bravo'])->create(); + + $this->simulateColdStache(); + + // Loading a non-URI index first triggers re-entrant URI index loading via getCachedItem(). + Stache::store('entries')->store('pages')->index('site')->load(); + + $entries = Entry::query() + ->where('collection', 'pages') + ->whereNotNull('uri') + ->whereStatus('published') + ->get(); + + $this->assertGreaterThanOrEqual(2, $entries->count(), 'Expected at least 2 entries with URI on cold stache'); + } + + #[Test] + public function entries_have_uris_on_cold_stache_with_multisite_structured_collection() + { + $this->setSites([ + 'en' => ['url' => 'http://localhost/', 'locale' => 'en_US'], + 'fr' => ['url' => 'http://localhost/fr/', 'locale' => 'fr_FR'], + ]); + + $collection = Collection::make('pages') + ->routes('{parent_uri}/{slug}') + ->structureContents(['root' => true]) + ->sites(['en', 'fr']); + $collection->save(); + + EntryFactory::id('alfa-id')->locale('en')->collection('pages')->slug('alfa')->data(['title' => 'Alfa'])->create(); + EntryFactory::id('bravo-id')->locale('fr')->collection('pages')->slug('bravo')->origin('alfa-id')->data(['title' => 'Bravo'])->create(); + + $this->simulateColdStache(); + + Stache::store('entries')->store('pages')->index('site')->load(); + + $entries = Entry::query() + ->where('collection', 'pages') + ->whereNotNull('uri') + ->whereStatus('published') + ->get(); + + $this->assertGreaterThanOrEqual(1, $entries->count(), 'Expected at least 1 entry with URI on cold stache'); + } +}