@@ -217,7 +217,9 @@ public function get(string $locale, string $slug): array
217217 }
218218
219219 $ mtime = File::lastModified ($ path );
220- $ cacheKey = 'pertuk:docs: ' .$ locale .': ' .md5 ($ path .': ' .$ mtime );
220+ // Use realpath to ensure consistent cache keys regardless of symlinks/relative paths
221+ $ realPath = realpath ($ path ) ?: $ path ;
222+ $ cacheKey = 'pertuk:docs: ' .$ locale .': ' .md5 ($ realPath .': ' .$ mtime );
221223
222224 // Get cached value and validate it
223225 $ cached = Cache::get ($ cacheKey );
@@ -247,6 +249,12 @@ private function isValidCachedDocument(mixed $data): bool
247249 private function generateDocumentData (string $ path , string $ locale , string $ slug , int $ mtime ): array
248250 {
249251 $ raw = File::get ($ path );
252+
253+ // @phpstan-ignore-next-line
254+ if (! is_string ($ raw )) {
255+ throw new \RuntimeException ("Failed to read file: {$ path }" );
256+ }
257+
250258 try {
251259 $ front = YamlFrontMatter::parse ($ raw );
252260 $ content = $ front ->body ();
@@ -424,15 +432,16 @@ protected function buildAlternates(string $locale, string $slug): array
424432 $ supported = (array ) config ('pertuk.supported_locales ' , ['en ' ]);
425433
426434 $ labels = (array ) config ('pertuk.locale_labels ' , []);
427- $ prefix = config ('pertuk.route_prefix ' , 'docs ' );
435+ $ prefix = ( string ) config ('pertuk.route_prefix ' , 'docs ' );
428436
429437 $ alternates = [];
430438 foreach ($ supported as $ loc ) {
439+ $ loc = (string ) $ loc ;
431440 $ path = $ this ->resolvePath ($ loc , $ slug );
432441 if ($ path ) {
433442 $ alternates [] = [
434443 'locale ' => $ loc ,
435- 'label ' => $ labels [$ loc ] ?? strtoupper ($ loc ),
444+ 'label ' => ( string ) ( $ labels [$ loc ] ?? strtoupper ($ loc) ),
436445 'url ' => url ('/ ' .$ prefix .'/ ' .($ this ->version ? $ this ->version .'/ ' : '' ).$ loc .'/ ' .$ slug ),
437446 'active ' => $ loc === $ locale ,
438447 ];
0 commit comments