xref: /template/strap/ComboStrap/IFetcherAbs.php (revision 04fd306c7c155fa133ebb3669986875d65988276)
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