Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions _test/MediaLinkResolverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down
2 changes: 1 addition & 1 deletion src/DokuAssetFetcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
7 changes: 4 additions & 3 deletions src/MediaLinkResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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).
Expand All @@ -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)
Expand Down