1*da933f89SLORTET<?php 2*da933f89SLORTETif (!defined('DOKU_INC')) die(); 3*da933f89SLORTET 4*da933f89SLORTETclass helper_plugin_pagesicon extends DokuWiki_Plugin 5*da933f89SLORTET{ 6*da933f89SLORTET private function getMediaMTime(string $mediaID): int 7*da933f89SLORTET { 8*da933f89SLORTET $mediaID = cleanID($mediaID); 9*da933f89SLORTET if ($mediaID === '') return 0; 10*da933f89SLORTET $file = mediaFN($mediaID); 11*da933f89SLORTET if (!@file_exists($file)) return 0; 12*da933f89SLORTET $mtime = @filemtime($file); 13*da933f89SLORTET return $mtime ? (int)$mtime : 0; 14*da933f89SLORTET } 15*da933f89SLORTET 16*da933f89SLORTET private function appendVersionToUrl(string $url, int $mtime): string 17*da933f89SLORTET { 18*da933f89SLORTET if ($url === '' || $mtime <= 0) return $url; 19*da933f89SLORTET $sep = strpos($url, '?') === false ? '?' : '&'; 20*da933f89SLORTET return $url . $sep . 'pi_ts=' . $mtime; 21*da933f89SLORTET } 22*da933f89SLORTET 23*da933f89SLORTET public function notifyIconUpdated(string $targetPage, string $action = 'update', string $mediaID = ''): void 24*da933f89SLORTET { 25*da933f89SLORTET global $conf; 26*da933f89SLORTET 27*da933f89SLORTET @io_saveFile($conf['cachedir'] . '/purgefile', time()); 28*da933f89SLORTET 29*da933f89SLORTET $data = [ 30*da933f89SLORTET 'target_page' => cleanID($targetPage), 31*da933f89SLORTET 'action' => $action, 32*da933f89SLORTET 'media_id' => cleanID($mediaID), 33*da933f89SLORTET ]; 34*da933f89SLORTET \dokuwiki\Extension\Event::createAndTrigger('PLUGIN_PAGESICON_UPDATED', $data); 35*da933f89SLORTET } 36*da933f89SLORTET 37*da933f89SLORTET private function buildConfiguredCandidatesFromRaw(string $raw, string $namespace, string $pageID): array 38*da933f89SLORTET { 39*da933f89SLORTET $configured = []; 40*da933f89SLORTET $entries = array_filter(array_map('trim', explode(';', $raw))); 41*da933f89SLORTET 42*da933f89SLORTET foreach ($entries as $entry) { 43*da933f89SLORTET $name = str_replace('~pagename~', $pageID, $entry); 44*da933f89SLORTET if ($name === '') continue; 45*da933f89SLORTET 46*da933f89SLORTET if (strpos($name, ':') === false && $namespace !== '') { 47*da933f89SLORTET $configured[] = $namespace . ':' . $name; 48*da933f89SLORTET } else { 49*da933f89SLORTET $configured[] = ltrim($name, ':'); 50*da933f89SLORTET } 51*da933f89SLORTET } 52*da933f89SLORTET 53*da933f89SLORTET return array_values(array_unique($configured)); 54*da933f89SLORTET } 55*da933f89SLORTET 56*da933f89SLORTET private function buildConfiguredCandidates(string $namespace, string $pageID, string $sizeMode): array 57*da933f89SLORTET { 58*da933f89SLORTET $bigRaw = trim((string)$this->getConf('icon_name')); 59*da933f89SLORTET $smallRaw = trim((string)$this->getConf('icon_thumbnail_name')); 60*da933f89SLORTET 61*da933f89SLORTET $big = $this->buildConfiguredCandidatesFromRaw($bigRaw, $namespace, $pageID); 62*da933f89SLORTET $small = $this->buildConfiguredCandidatesFromRaw($smallRaw, $namespace, $pageID); 63*da933f89SLORTET 64*da933f89SLORTET if ($sizeMode === 'big') return $big; 65*da933f89SLORTET if ($sizeMode === 'small') return $small; 66*da933f89SLORTET if ($sizeMode === 'smallorbig') return array_values(array_unique(array_merge($small, $big))); 67*da933f89SLORTET 68*da933f89SLORTET // Default: bigorsmall 69*da933f89SLORTET return array_values(array_unique(array_merge($big, $small))); 70*da933f89SLORTET } 71*da933f89SLORTET 72*da933f89SLORTET private function normalizeSizeMode(string $size): string 73*da933f89SLORTET { 74*da933f89SLORTET $size = strtolower(trim($size)); 75*da933f89SLORTET $allowed = ['big', 'small', 'bigorsmall', 'smallorbig']; 76*da933f89SLORTET if (in_array($size, $allowed, true)) return $size; 77*da933f89SLORTET return 'bigorsmall'; 78*da933f89SLORTET } 79*da933f89SLORTET 80*da933f89SLORTET private function getExtensions(): array 81*da933f89SLORTET { 82*da933f89SLORTET $raw = trim((string)$this->getConf('extensions')); 83*da933f89SLORTET if ($raw === '') return ['svg', 'png', 'jpg', 'jpeg']; 84*da933f89SLORTET 85*da933f89SLORTET $extensions = array_values(array_unique(array_filter(array_map(function ($ext) { 86*da933f89SLORTET return strtolower(ltrim(trim((string)$ext), '.')); 87*da933f89SLORTET }, explode(';', $raw))))); 88*da933f89SLORTET 89*da933f89SLORTET return $extensions ?: ['svg', 'png', 'jpg', 'jpeg']; 90*da933f89SLORTET } 91*da933f89SLORTET 92*da933f89SLORTET private function hasKnownExtension(string $name, array $extensions): bool 93*da933f89SLORTET { 94*da933f89SLORTET $fileExt = strtolower((string)pathinfo($name, PATHINFO_EXTENSION)); 95*da933f89SLORTET return $fileExt !== '' && in_array($fileExt, $extensions, true); 96*da933f89SLORTET } 97*da933f89SLORTET 98*da933f89SLORTET public function getPageImage(string $namespace, string $pageID, string $size = 'bigorsmall') 99*da933f89SLORTET { 100*da933f89SLORTET $sizeMode = $this->normalizeSizeMode($size); 101*da933f89SLORTET $extensions = $this->getExtensions(); 102*da933f89SLORTET $namespace = $namespace ?: ''; 103*da933f89SLORTET $pageBase = $namespace ? ($namespace . ':' . $pageID) : $pageID; 104*da933f89SLORTET $nsBase = $namespace ? ($namespace . ':') : ''; 105*da933f89SLORTET 106*da933f89SLORTET $genericBig = [ 107*da933f89SLORTET $pageBase, 108*da933f89SLORTET $pageBase . ':logo', 109*da933f89SLORTET $nsBase . 'logo', 110*da933f89SLORTET ]; 111*da933f89SLORTET $genericSmall = [ 112*da933f89SLORTET $pageBase . ':thumbnail', 113*da933f89SLORTET $nsBase . 'thumbnail', 114*da933f89SLORTET ]; 115*da933f89SLORTET 116*da933f89SLORTET if ($sizeMode === 'big') { 117*da933f89SLORTET $generic = $genericBig; 118*da933f89SLORTET } elseif ($sizeMode === 'small') { 119*da933f89SLORTET $generic = $genericSmall; 120*da933f89SLORTET } elseif ($sizeMode === 'smallorbig') { 121*da933f89SLORTET $generic = array_merge($genericSmall, $genericBig); 122*da933f89SLORTET } else { 123*da933f89SLORTET $generic = array_merge($genericBig, $genericSmall); 124*da933f89SLORTET } 125*da933f89SLORTET 126*da933f89SLORTET $imageNames = array_merge($this->buildConfiguredCandidates($namespace, $pageID, $sizeMode), $generic); 127*da933f89SLORTET 128*da933f89SLORTET foreach ($imageNames as $name) { 129*da933f89SLORTET if ($this->hasKnownExtension($name, $extensions)) { 130*da933f89SLORTET if (@file_exists(mediaFN($name))) return $name; 131*da933f89SLORTET continue; 132*da933f89SLORTET } 133*da933f89SLORTET 134*da933f89SLORTET foreach ($extensions as $ext) { 135*da933f89SLORTET $path = $name . '.' . $ext; 136*da933f89SLORTET if (@file_exists(mediaFN($path))) return $path; 137*da933f89SLORTET } 138*da933f89SLORTET } 139*da933f89SLORTET 140*da933f89SLORTET return false; 141*da933f89SLORTET } 142*da933f89SLORTET 143*da933f89SLORTET public function getUploadIconPage(string $targetPage = '') 144*da933f89SLORTET { 145*da933f89SLORTET global $ID; 146*da933f89SLORTET 147*da933f89SLORTET $targetPage = cleanID($targetPage); 148*da933f89SLORTET if ($targetPage === '') { 149*da933f89SLORTET $targetPage = cleanID(getNS((string)$ID)); 150*da933f89SLORTET } 151*da933f89SLORTET if ($targetPage === '') { 152*da933f89SLORTET $targetPage = cleanID((string)$ID); 153*da933f89SLORTET } 154*da933f89SLORTET if ($targetPage === '') return null; 155*da933f89SLORTET 156*da933f89SLORTET if (auth_quickaclcheck($targetPage) < AUTH_UPLOAD) { 157*da933f89SLORTET return null; 158*da933f89SLORTET } 159*da933f89SLORTET 160*da933f89SLORTET return wl($targetPage, ['do' => 'pagesicon']); 161*da933f89SLORTET } 162*da933f89SLORTET 163*da933f89SLORTET public function getMediaImage(string $mediaID, string $size = 'bigorsmall') 164*da933f89SLORTET { 165*da933f89SLORTET $mediaID = cleanID($mediaID); 166*da933f89SLORTET if ($mediaID === '') return false; 167*da933f89SLORTET 168*da933f89SLORTET $namespace = getNS($mediaID); 169*da933f89SLORTET $filename = noNS($mediaID); 170*da933f89SLORTET $base = (string)pathinfo($filename, PATHINFO_FILENAME); 171*da933f89SLORTET $pageID = cleanID($base); 172*da933f89SLORTET if ($pageID === '') return false; 173*da933f89SLORTET 174*da933f89SLORTET return $this->getPageImage($namespace, $pageID, $size); 175*da933f89SLORTET } 176*da933f89SLORTET 177*da933f89SLORTET public function getImageIcon( 178*da933f89SLORTET string $namespace, 179*da933f89SLORTET string $pageID, 180*da933f89SLORTET string $size = 'bigorsmall', 181*da933f89SLORTET array $params = ['width' => 55], 182*da933f89SLORTET ?int &$mtime = null 183*da933f89SLORTET ) { 184*da933f89SLORTET $mediaID = $this->getPageImage($namespace, $pageID, $size); 185*da933f89SLORTET if (!$mediaID) { 186*da933f89SLORTET $mtime = 0; 187*da933f89SLORTET return false; 188*da933f89SLORTET } 189*da933f89SLORTET 190*da933f89SLORTET $mtime = $this->getMediaMTime((string)$mediaID); 191*da933f89SLORTET $url = (string)ml((string)$mediaID, $params); 192*da933f89SLORTET if ($url === '') return false; 193*da933f89SLORTET return $this->appendVersionToUrl($url, $mtime); 194*da933f89SLORTET } 195*da933f89SLORTET 196*da933f89SLORTET public function getMediaIcon( 197*da933f89SLORTET string $mediaID, 198*da933f89SLORTET string $size = 'bigorsmall', 199*da933f89SLORTET array $params = ['width' => 55], 200*da933f89SLORTET ?int &$mtime = null 201*da933f89SLORTET ) { 202*da933f89SLORTET $iconMediaID = $this->getMediaImage($mediaID, $size); 203*da933f89SLORTET if (!$iconMediaID) { 204*da933f89SLORTET $mtime = 0; 205*da933f89SLORTET return false; 206*da933f89SLORTET } 207*da933f89SLORTET 208*da933f89SLORTET $mtime = $this->getMediaMTime((string)$iconMediaID); 209*da933f89SLORTET $url = (string)ml((string)$iconMediaID, $params); 210*da933f89SLORTET if ($url === '') return false; 211*da933f89SLORTET return $this->appendVersionToUrl($url, $mtime); 212*da933f89SLORTET } 213*da933f89SLORTET 214*da933f89SLORTET public function getUploadMediaIconPage(string $mediaID = '') 215*da933f89SLORTET { 216*da933f89SLORTET $mediaID = cleanID($mediaID); 217*da933f89SLORTET if ($mediaID === '') return null; 218*da933f89SLORTET 219*da933f89SLORTET $namespace = getNS($mediaID); 220*da933f89SLORTET $filename = noNS($mediaID); 221*da933f89SLORTET $base = (string)pathinfo($filename, PATHINFO_FILENAME); 222*da933f89SLORTET $targetPage = cleanID($namespace !== '' ? ($namespace . ':' . $base) : $base); 223*da933f89SLORTET if ($targetPage === '') return null; 224*da933f89SLORTET 225*da933f89SLORTET return $this->getUploadIconPage($targetPage); 226*da933f89SLORTET } 227*da933f89SLORTET} 228