1*04fd306cSNickeau<?php 2*04fd306cSNickeau 3*04fd306cSNickeau 4*04fd306cSNickeaunamespace ComboStrap; 5*04fd306cSNickeau 6*04fd306cSNickeauuse ComboStrap\Web\Url; 7*04fd306cSNickeauuse ComboStrap\Web\UrlEndpoint; 8*04fd306cSNickeau 9*04fd306cSNickeau/** 10*04fd306cSNickeau * Class Media 11*04fd306cSNickeau * @package ComboStrap 12*04fd306cSNickeau * 13*04fd306cSNickeau * 14*04fd306cSNickeau * This is why there is a cache attribute - this is the cache of the generated file 15*04fd306cSNickeau * if any 16*04fd306cSNickeau */ 17*04fd306cSNickeauabstract class IFetcherAbs implements IFetcher 18*04fd306cSNickeau{ 19*04fd306cSNickeau 20*04fd306cSNickeau public const NOCACHE_VALUE = "nocache"; 21*04fd306cSNickeau const RECACHE_VALUE = "recache"; 22*04fd306cSNickeau private ?string $requestedCache = null; 23*04fd306cSNickeau 24*04fd306cSNickeau /** 25*04fd306cSNickeau * Doc: https://www.dokuwiki.org/images#caching 26*04fd306cSNickeau * Cache 27*04fd306cSNickeau * values: 28*04fd306cSNickeau * * cache 29*04fd306cSNickeau * * nocache 30*04fd306cSNickeau * * recache 31*04fd306cSNickeau */ 32*04fd306cSNickeau public const CACHE_KEY = 'cache'; 33*04fd306cSNickeau public const CACHE_DEFAULT_VALUE = "cache"; 34*04fd306cSNickeau 35*04fd306cSNickeau 36*04fd306cSNickeau private string $requestedUrlFragment; 37*04fd306cSNickeau 38*04fd306cSNickeau 39*04fd306cSNickeau /** 40*04fd306cSNickeau * @param Url|null $url 41*04fd306cSNickeau * @return Url 42*04fd306cSNickeau */ 43*04fd306cSNickeau function getFetchUrl(Url $url = null): Url 44*04fd306cSNickeau { 45*04fd306cSNickeau 46*04fd306cSNickeau if ($url === null) { 47*04fd306cSNickeau $url = UrlEndpoint::createFetchUrl(); 48*04fd306cSNickeau } 49*04fd306cSNickeau 50*04fd306cSNickeau try { 51*04fd306cSNickeau $url->setFragment($this->getRequestedUrlFragment()); 52*04fd306cSNickeau } catch (ExceptionNotFound $e) { 53*04fd306cSNickeau // no fragment 54*04fd306cSNickeau } 55*04fd306cSNickeau 56*04fd306cSNickeau /** 57*04fd306cSNickeau * The cache 58*04fd306cSNickeau */ 59*04fd306cSNickeau try { 60*04fd306cSNickeau $value = $this->getRequestedCache(); 61*04fd306cSNickeau if ($value !== self::CACHE_DEFAULT_VALUE) { 62*04fd306cSNickeau $url->setQueryParameter(self::CACHE_KEY, $value); 63*04fd306cSNickeau } 64*04fd306cSNickeau } catch (ExceptionNotFound $e) { 65*04fd306cSNickeau // ok 66*04fd306cSNickeau } 67*04fd306cSNickeau 68*04fd306cSNickeau /** 69*04fd306cSNickeau * The buster 70*04fd306cSNickeau */ 71*04fd306cSNickeau try { 72*04fd306cSNickeau $buster = $this->getBuster(); 73*04fd306cSNickeau if ($buster !== "") { 74*04fd306cSNickeau $url->setQueryParameter(IFetcher::CACHE_BUSTER_KEY, $buster); 75*04fd306cSNickeau } 76*04fd306cSNickeau } catch (ExceptionNotFound $e) { 77*04fd306cSNickeau // 78*04fd306cSNickeau } 79*04fd306cSNickeau 80*04fd306cSNickeau 81*04fd306cSNickeau /** 82*04fd306cSNickeau * The fetcher name 83*04fd306cSNickeau */ 84*04fd306cSNickeau $fetcherName = $this->getFetcherName(); 85*04fd306cSNickeau $url->setQueryParameter(IFetcher::FETCHER_KEY, $fetcherName); 86*04fd306cSNickeau 87*04fd306cSNickeau return $url; 88*04fd306cSNickeau } 89*04fd306cSNickeau 90*04fd306cSNickeau 91*04fd306cSNickeau /** 92*04fd306cSNickeau * @throws ExceptionBadArgument 93*04fd306cSNickeau */ 94*04fd306cSNickeau public function buildFromUrl(Url $url): IFetcher 95*04fd306cSNickeau { 96*04fd306cSNickeau $query = $url->getQueryProperties(); 97*04fd306cSNickeau $tagAttributes = TagAttributes::createFromCallStackArray($query); 98*04fd306cSNickeau $this->buildFromTagAttributes($tagAttributes); 99*04fd306cSNickeau try { 100*04fd306cSNickeau $this->setRequestedUrlFragment($url->getFragment()); 101*04fd306cSNickeau } catch (ExceptionNotFound $e) { 102*04fd306cSNickeau // no fragment 103*04fd306cSNickeau } 104*04fd306cSNickeau return $this; 105*04fd306cSNickeau } 106*04fd306cSNickeau 107*04fd306cSNickeau /** 108*04fd306cSNickeau * @throws ExceptionBadArgument 109*04fd306cSNickeau */ 110*04fd306cSNickeau public function buildFromTagAttributes(TagAttributes $tagAttributes): IFetcher 111*04fd306cSNickeau { 112*04fd306cSNickeau 113*04fd306cSNickeau $cache = $tagAttributes->getValueAndRemove(self::CACHE_KEY); 114*04fd306cSNickeau if ($cache !== null) { 115*04fd306cSNickeau $this->setRequestedCache($cache); 116*04fd306cSNickeau } 117*04fd306cSNickeau 118*04fd306cSNickeau return $this; 119*04fd306cSNickeau 120*04fd306cSNickeau } 121*04fd306cSNickeau 122*04fd306cSNickeau /** 123*04fd306cSNickeau * @return string $cache - one of {@link FetcherCache::CACHE_KEY} 124*04fd306cSNickeau * @throws ExceptionNotFound 125*04fd306cSNickeau */ 126*04fd306cSNickeau public function getRequestedCache(): string 127*04fd306cSNickeau { 128*04fd306cSNickeau if ($this->requestedCache === null) { 129*04fd306cSNickeau throw new ExceptionNotFound("No cache was requested"); 130*04fd306cSNickeau } 131*04fd306cSNickeau return $this->requestedCache; 132*04fd306cSNickeau } 133*04fd306cSNickeau 134*04fd306cSNickeau /** 135*04fd306cSNickeau * 136*04fd306cSNickeau * @throws ExceptionBadArgument 137*04fd306cSNickeau */ 138*04fd306cSNickeau public function setRequestedCache(string $requestedCache) 139*04fd306cSNickeau { 140*04fd306cSNickeau /** 141*04fd306cSNickeau * Cache transformation 142*04fd306cSNickeau * From Image cache value (https://www.dokuwiki.org/images#caching) 143*04fd306cSNickeau * to {@link FetcherCache::setMaxAgeInSec()} 144*04fd306cSNickeau */ 145*04fd306cSNickeau switch ($requestedCache) { 146*04fd306cSNickeau case "nocache": 147*04fd306cSNickeau case self::RECACHE_VALUE: 148*04fd306cSNickeau case "cache": 149*04fd306cSNickeau $this->requestedCache = $requestedCache; 150*04fd306cSNickeau break; 151*04fd306cSNickeau default: 152*04fd306cSNickeau throw new ExceptionBadArgument("The cache value ($requestedCache) is unknown"); 153*04fd306cSNickeau } 154*04fd306cSNickeau } 155*04fd306cSNickeau 156*04fd306cSNickeau /** 157*04fd306cSNickeau * Get cache age from cache property 158*04fd306cSNickeau * 159*04fd306cSNickeau * to {@link FetcherCache::setMaxAgeInSec()} 160*04fd306cSNickeau */ 161*04fd306cSNickeau public function getCacheMaxAgeInSec(string $cacheValue): int 162*04fd306cSNickeau { 163*04fd306cSNickeau /** 164*04fd306cSNickeau * From the Dokuwiki Rule 165*04fd306cSNickeau * From Image cache value (https://www.dokuwiki.org/images#caching) 166*04fd306cSNickeau * and https://www.dokuwiki.org/devel:event:fetch_media_status 167*04fd306cSNickeau * 168*04fd306cSNickeau * Not if a value is passed numerically inside dokuwiki, this rule applies 169*04fd306cSNickeau * $maxAge < 0 // cache forever 170*04fd306cSNickeau * $maxAge === 0 // never cache 171*04fd306cSNickeau * $maxAge > 0 // cache for a number of seconds 172*04fd306cSNickeau */ 173*04fd306cSNickeau switch ($cacheValue) { 174*04fd306cSNickeau case "nocache": 175*04fd306cSNickeau case "no": 176*04fd306cSNickeau // never cache 177*04fd306cSNickeau return 0; 178*04fd306cSNickeau case self::RECACHE_VALUE: 179*04fd306cSNickeau case "re": 180*04fd306cSNickeau return Site::getXhtmlCacheTime(); 181*04fd306cSNickeau case "cache": 182*04fd306cSNickeau default: 183*04fd306cSNickeau // cache forever 184*04fd306cSNickeau return PHP_INT_MAX; 185*04fd306cSNickeau 186*04fd306cSNickeau } 187*04fd306cSNickeau 188*04fd306cSNickeau 189*04fd306cSNickeau } 190*04fd306cSNickeau 191*04fd306cSNickeau /** 192*04fd306cSNickeau * 193*04fd306cSNickeau * The fragment may be used by plugin to jump into a media. 194*04fd306cSNickeau * This is the case of the PDF plugin 195*04fd306cSNickeau * @param string $urlFragment a fragment added to the {@link IFetcher::getFetchUrl() fetch URL} 196*04fd306cSNickeau */ 197*04fd306cSNickeau public function setRequestedUrlFragment(string $urlFragment): IFetcher 198*04fd306cSNickeau { 199*04fd306cSNickeau $this->requestedUrlFragment = $urlFragment; 200*04fd306cSNickeau return $this; 201*04fd306cSNickeau } 202*04fd306cSNickeau 203*04fd306cSNickeau /** 204*04fd306cSNickeau * @throws ExceptionNotFound 205*04fd306cSNickeau */ 206*04fd306cSNickeau public function getRequestedUrlFragment(): string 207*04fd306cSNickeau { 208*04fd306cSNickeau 209*04fd306cSNickeau if (!isset($this->requestedUrlFragment)) { 210*04fd306cSNickeau throw new ExceptionNotFound("No url fragment was requested"); 211*04fd306cSNickeau } 212*04fd306cSNickeau return $this->requestedUrlFragment; 213*04fd306cSNickeau 214*04fd306cSNickeau } 215*04fd306cSNickeau 216*04fd306cSNickeau public function getContentCachePath(): LocalPath 217*04fd306cSNickeau { 218*04fd306cSNickeau throw new ExceptionNotSupported("No cache support by default, overwrite this function to give access to your cache path"); 219*04fd306cSNickeau } 220*04fd306cSNickeau 221*04fd306cSNickeau public function process(): IFetcher 222*04fd306cSNickeau { 223*04fd306cSNickeau throw new ExceptionNotSupported("The fetcher ($this) does not support to feed the cache, overwrite this function to give access to this functionality"); 224*04fd306cSNickeau } 225*04fd306cSNickeau 226*04fd306cSNickeau public function __toString() 227*04fd306cSNickeau { 228*04fd306cSNickeau return get_class($this); 229*04fd306cSNickeau } 230*04fd306cSNickeau 231*04fd306cSNickeau 232*04fd306cSNickeau} 233