190 lines
6.6 KiB
PHP
190 lines
6.6 KiB
PHP
<?php
|
|
|
|
namespace dokuwiki\plugin\luxtools;
|
|
|
|
/**
|
|
* Shared utility for thumbnail cache management and display logic.
|
|
*
|
|
* Used by both the image syntax and the gallery rendering to avoid code duplication.
|
|
*/
|
|
class ThumbnailHelper
|
|
{
|
|
/**
|
|
* Get thumbnail URL and metadata for rendering.
|
|
*
|
|
* This is the main entry point for getting thumbnails. The helper handles
|
|
* all URL construction, cache checking, and provides ready-to-use URLs.
|
|
*
|
|
* @param string $rootPath Root filesystem path (e.g., '/data/images/')
|
|
* @param string $localPath Local path relative to root (e.g., 'photo.jpg')
|
|
* @param string $pageId Page ID for ACL check
|
|
* @param int $width Desired width
|
|
* @param int $height Desired height
|
|
* @param int $quality JPEG quality (0-100)
|
|
* @param string|null $placeholderId Optional MediaManager ID for custom placeholder
|
|
* @return array [
|
|
* 'url' => string, // Always usable URL (thumbnail or placeholder)
|
|
* 'isFinal' => bool, // true if thumbnail ready, false if placeholder
|
|
* 'thumbUrl' => string // Real thumbnail URL (for lazy loading)
|
|
* ]
|
|
*/
|
|
public static function getThumbnail(
|
|
string $rootPath,
|
|
string $localPath,
|
|
string $pageId,
|
|
int $width,
|
|
int $height,
|
|
int $quality = 80,
|
|
?string $placeholderId = null
|
|
): array {
|
|
$fullPath = $rootPath . $localPath;
|
|
$thumbUrl = self::buildThumbnailUrl($rootPath, $localPath, $pageId, $width, $height, $quality);
|
|
|
|
// Check if cached
|
|
$cachePath = self::getCachePath($fullPath, $width, $height, $quality);
|
|
$isCached = $cachePath !== null && @is_file($cachePath);
|
|
|
|
if ($isCached) {
|
|
return [
|
|
'url' => $thumbUrl,
|
|
'isFinal' => true,
|
|
'thumbUrl' => $thumbUrl,
|
|
];
|
|
}
|
|
|
|
// Not cached: return placeholder
|
|
return [
|
|
'url' => self::getPlaceholderUrl($width, $height, $placeholderId),
|
|
'isFinal' => false,
|
|
'thumbUrl' => $thumbUrl,
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Build the file.php URL for a thumbnail.
|
|
*
|
|
* @param string $rootPath Root filesystem path
|
|
* @param string $localPath Local path relative to root
|
|
* @param string $pageId Page ID for ACL check
|
|
* @param int $width Width
|
|
* @param int $height Height
|
|
* @param int $quality JPEG quality
|
|
* @return string Complete URL to file.php with thumbnail parameters
|
|
*/
|
|
protected static function buildThumbnailUrl(
|
|
string $rootPath,
|
|
string $localPath,
|
|
string $pageId,
|
|
int $width,
|
|
int $height,
|
|
int $quality
|
|
): string {
|
|
$params = [
|
|
'root' => $rootPath,
|
|
'file' => $localPath,
|
|
'id' => $pageId,
|
|
'thumb' => 1,
|
|
'w' => $width,
|
|
'h' => $height,
|
|
'q' => $quality,
|
|
];
|
|
return DOKU_BASE . 'lib/plugins/luxtools/file.php?' . http_build_query($params, '', '&');
|
|
}
|
|
|
|
/**
|
|
* Compute the expected thumbnail cache path.
|
|
*
|
|
* Mirrors the hashing scheme in file.php so we can detect whether a thumb
|
|
* already exists and can be used immediately.
|
|
*
|
|
* @param string $path Full filesystem path to the image
|
|
* @param int $w Width
|
|
* @param int $h Height
|
|
* @param int $q Quality (JPEG)
|
|
* @return string|null Path to cached thumbnail, or null if unavailable
|
|
*/
|
|
public static function getCachePath(string $path, int $w, int $h, int $q = 80): ?string
|
|
{
|
|
if ($path === '' || !is_file($path)) return null;
|
|
|
|
$mtime = @filemtime($path);
|
|
if ($mtime === false) return null;
|
|
|
|
// Decide output format the same way file.php does
|
|
try {
|
|
[, $mime,] = mimetype($path, false);
|
|
} catch (\Throwable $e) {
|
|
return null;
|
|
}
|
|
if (!is_string($mime) || !str_starts_with($mime, 'image/')) return null;
|
|
$dstFormat = ($mime === 'image/png' || $mime === 'image/gif') ? 'png' : 'jpg';
|
|
|
|
global $conf;
|
|
if (!isset($conf['cachedir']) || !is_string($conf['cachedir']) || trim($conf['cachedir']) === '') return null;
|
|
|
|
$hash = sha1($path . '|' . $mtime . '|w=' . $w . '|h=' . $h . '|q=' . $q . '|f=' . $dstFormat);
|
|
$sub = substr($hash, 0, 2);
|
|
$cacheDir = rtrim($conf['cachedir'], '/');
|
|
return $cacheDir . '/luxtools/thumbs/' . $sub . '/' . $hash . '.' . $dstFormat;
|
|
}
|
|
|
|
/**
|
|
* Get placeholder image URL.
|
|
*
|
|
* @param int $width Desired width
|
|
* @param int $height Desired height
|
|
* @param string|null $placeholderId Optional MediaManager ID for custom placeholder
|
|
* @return string Placeholder URL
|
|
*/
|
|
public static function getPlaceholderUrl(int $width, int $height, ?string $placeholderId = null): string
|
|
{
|
|
$placeholderUrl = DOKU_BASE . 'lib/images/blank.gif';
|
|
|
|
if ($placeholderId !== null && $placeholderId !== '' && function_exists('ml')) {
|
|
$placeholderUrl = ml($placeholderId, ['w' => $width, 'h' => $height], true, '&');
|
|
}
|
|
|
|
return $placeholderUrl;
|
|
}
|
|
|
|
/**
|
|
* Determine the initial image source and data attributes for lazy thumbnail loading.
|
|
*
|
|
* Returns placeholder info if thumbnail needs to be loaded, or the actual
|
|
* thumbnail URL if it's already cached.
|
|
*
|
|
* @param string $imagePath Full filesystem path to the image
|
|
* @param string $thumbUrl URL to the thumbnail
|
|
* @param int $width Width
|
|
* @param int $height Height
|
|
* @param int $quality Quality (JPEG)
|
|
* @param string|null $placeholderId Optional MediaManager ID for custom placeholder
|
|
* @return array ['src' => string, 'dataThumbAttr' => string]
|
|
*/
|
|
public static function getDisplayInfo(
|
|
string $imagePath,
|
|
string $thumbUrl,
|
|
int $width,
|
|
int $height,
|
|
int $quality = 80,
|
|
?string $placeholderId = null
|
|
): array {
|
|
$thumbCachePath = self::getCachePath($imagePath, $width, $height, $quality);
|
|
|
|
if ($thumbCachePath !== null && @is_file($thumbCachePath)) {
|
|
// Thumbnail exists: display it immediately
|
|
return [
|
|
'src' => $thumbUrl,
|
|
'dataThumbAttr' => '',
|
|
];
|
|
}
|
|
|
|
// Thumbnail doesn't exist: show placeholder and lazy-load
|
|
$placeholderUrl = self::getPlaceholderUrl($width, $height, $placeholderId);
|
|
return [
|
|
'src' => $placeholderUrl,
|
|
'dataThumbAttr' => ' data-thumb-src="' . hsc($thumbUrl) . '"',
|
|
];
|
|
}
|
|
}
|