diff --git a/_test/MediaLinkResolverTest.php b/_test/MediaLinkResolverTest.php index 7f8ce12..90cea47 100644 --- a/_test/MediaLinkResolverTest.php +++ b/_test/MediaLinkResolverTest.php @@ -101,6 +101,30 @@ public function testResolveFetchesExternalMedia(): void $this->assertSame(2523, filesize($resolved['path'])); } + /** + * External media must remain fetchable by mPDF when DokuWiki's local cache is disabled. + */ + public function testResolveFallsBackToExternalUrlWhenCachingIsDisabled(): void + { + global $conf; + + $fetchsize = $conf['fetchsize']; + $conf['fetchsize'] = 0; + + try { + $external = 'https://owncloud.example.org/index.php/s/token/download' + . '?path=%2F&files=image.jpg&t=token&.jpg'; + $input = DOKU_URL . 'lib/exe/fetch.php?media=' . rawurlencode($external); + $resolved = $this->resolver->resolve($input); + } finally { + $conf['fetchsize'] = $fetchsize; + } + + $this->assertNotNull($resolved); + $this->assertSame($external, $resolved['path']); + $this->assertSame('image/jpeg', $resolved['mime']); + } + /** * Non-image payloads should never be returned to the PDF generator. */ diff --git a/src/DokuAssetFetcher.php b/src/DokuAssetFetcher.php index 82d2688..b489053 100644 --- a/src/DokuAssetFetcher.php +++ b/src/DokuAssetFetcher.php @@ -12,7 +12,7 @@ class DokuAssetFetcher extends AssetFetcher public function fetchDataFromPath($path, $originalSrc = null) { $resolved = (new MediaLinkResolver())->resolve($path); - if ($resolved) $originalSrc = $resolved['path']; + if ($resolved) $path = $originalSrc = $resolved['path']; return parent::fetchDataFromPath($path, $originalSrc); } } diff --git a/src/MediaLinkResolver.php b/src/MediaLinkResolver.php index a51ee08..209ae11 100644 --- a/src/MediaLinkResolver.php +++ b/src/MediaLinkResolver.php @@ -30,7 +30,7 @@ public function resolve(string $file): ?array if (!$ext) return null; $localFile = $this->localMediaFile($mediaID, $ext, $rev); if (!$localFile) return null; - if (str_starts_with($mime, 'image/')) { + if (str_starts_with($mime, 'image/') && !media_isexternal($localFile)) { $localFile = $this->resizedMedia($localFile, $ext, $w, $h); } } else { @@ -93,7 +93,8 @@ protected function extractMediaParams(string $file): array * This method will download external media files to the local cache if needed. ACLs are * checked here as well. * - * Returns null when the media file is not accessible. + * Falls back to the original external URL when local caching is disabled or fails. + * Returns null when an internal media file is not accessible. * * @param string $mediaID A media ID or external URL. * @param string $ext File extension (used for external media caching). @@ -106,7 +107,7 @@ protected function localMediaFile(string $mediaID, string $ext, int $rev): ?stri if (media_isexternal($mediaID)) { $local = media_get_from_URL($mediaID, $ext, $conf['cachetime']); - if (!$local) return null; + if (!$local) return $mediaID; } else { $mediaID = cleanID($mediaID); // check permissions (namespace only)