xref: /plugin/combo/ComboStrap/CacheManager.php (revision 04fd306c7c155fa133ebb3669986875d65988276)
137748cd8SNickeau<?php
237748cd8SNickeau
337748cd8SNickeau
437748cd8SNickeaunamespace ComboStrap;
537748cd8SNickeau
637748cd8SNickeau
74cadd4f8SNickeauuse DateTime;
837748cd8SNickeau
94cadd4f8SNickeau/**
104cadd4f8SNickeau * Class CacheManager
114cadd4f8SNickeau * @package ComboStrap
124cadd4f8SNickeau *
13*04fd306cSNickeau * The cache manager handles all things cache
14*04fd306cSNickeau * This is just another namespace extension of {@link ExecutionContext}
15*04fd306cSNickeau * to not have all function in the same place
16*04fd306cSNickeau *
17*04fd306cSNickeau * Except for the cache dependencies of a {@link FetcherMarkup::getOutputCacheDependencies() Markup}
184cadd4f8SNickeau */
1937748cd8SNickeauclass CacheManager
2037748cd8SNickeau{
2137748cd8SNickeau
224cadd4f8SNickeau
234cadd4f8SNickeau    const CACHE_DELETION = "deletion";
244cadd4f8SNickeau    const CACHE_CREATION = "creation";
254cadd4f8SNickeau
2637748cd8SNickeau
2737748cd8SNickeau    /**
28*04fd306cSNickeau     * The list of cache runtimes dependencies by slot {@link MarkupCacheDependencies}
2937748cd8SNickeau     */
30*04fd306cSNickeau    private array $slotCacheDependencies = [];
31c3437056SNickeau
324cadd4f8SNickeau    /**
334cadd4f8SNickeau     * The list of cache results slot {@link CacheResults}
344cadd4f8SNickeau     */
35*04fd306cSNickeau    private array $slotCacheResults = [];
364cadd4f8SNickeau
374cadd4f8SNickeau    /**
384cadd4f8SNickeau     * @var array hold the result for slot cache expiration
394cadd4f8SNickeau     */
40*04fd306cSNickeau    private array $slotsExpiration = [];
41*04fd306cSNickeau
42*04fd306cSNickeau
43*04fd306cSNickeau    private ExecutionContext $executionContext;
44*04fd306cSNickeau
45*04fd306cSNickeau    public function __construct(ExecutionContext $executionContext)
46*04fd306cSNickeau    {
47*04fd306cSNickeau        $this->executionContext = $executionContext;
48*04fd306cSNickeau    }
4937748cd8SNickeau
5037748cd8SNickeau
5137748cd8SNickeau    /**
5237748cd8SNickeau     * @return CacheManager
53*04fd306cSNickeau     * @deprecated use the {@link ExecutionContext::getCacheManager()} instead otherwise you may mix context run
5437748cd8SNickeau     */
55*04fd306cSNickeau    public static function getFromContextExecution(): CacheManager
564cadd4f8SNickeau    {
574cadd4f8SNickeau
58*04fd306cSNickeau        return ExecutionContext::getActualOrCreateFromEnv()->getCacheManager();
594cadd4f8SNickeau
604cadd4f8SNickeau    }
614cadd4f8SNickeau
62*04fd306cSNickeau
63*04fd306cSNickeau
64*04fd306cSNickeau    public function &getCacheResultsForSlot(string $id): CacheResults
6537748cd8SNickeau    {
66*04fd306cSNickeau        $cacheManagerForSlot = &$this->slotCacheResults[$id];
674cadd4f8SNickeau        if ($cacheManagerForSlot === null) {
684cadd4f8SNickeau            $cacheManagerForSlot = new CacheResults($id);
694cadd4f8SNickeau            $this->slotCacheResults[$id] = $cacheManagerForSlot;
704cadd4f8SNickeau        }
714cadd4f8SNickeau        return $cacheManagerForSlot;
724cadd4f8SNickeau    }
734cadd4f8SNickeau
744cadd4f8SNickeau    /**
75*04fd306cSNickeau     * @return CacheResults[] - null if the page does not exists
764cadd4f8SNickeau     */
77*04fd306cSNickeau    public function getCacheResults(): array
784cadd4f8SNickeau    {
794cadd4f8SNickeau        return $this->slotCacheResults;
804cadd4f8SNickeau    }
814cadd4f8SNickeau
824cadd4f8SNickeau    /**
834cadd4f8SNickeau     */
844cadd4f8SNickeau    public function shouldSlotExpire($pageId): bool
854cadd4f8SNickeau    {
864cadd4f8SNickeau
874cadd4f8SNickeau        /**
884cadd4f8SNickeau         * Because of the recursive nature of rendering
894cadd4f8SNickeau         * inside dokuwiki, we just return a result for
904cadd4f8SNickeau         * the first call to the function
9137748cd8SNickeau         *
9237748cd8SNickeau         */
934cadd4f8SNickeau        if (isset($this->slotsExpiration[$pageId])) {
944cadd4f8SNickeau            return false;
9537748cd8SNickeau        }
964cadd4f8SNickeau
97*04fd306cSNickeau        $page = MarkupPath::createMarkupFromId($pageId);
98*04fd306cSNickeau        try {
994cadd4f8SNickeau            $cacheExpirationFrequency = CacheExpirationFrequency::createForPage($page)
1004cadd4f8SNickeau                ->getValue();
101*04fd306cSNickeau        } catch (ExceptionNotFound $e) {
1024cadd4f8SNickeau            $this->slotsExpiration[$pageId] = false;
1034cadd4f8SNickeau            return false;
10437748cd8SNickeau        }
10537748cd8SNickeau
1064cadd4f8SNickeau        $cacheExpirationDateMeta = CacheExpirationDate::createForPage($page);
107*04fd306cSNickeau        try {
1084cadd4f8SNickeau            $expirationDate = $cacheExpirationDateMeta->getValue();
109*04fd306cSNickeau        } catch (ExceptionNotFound $e) {
110*04fd306cSNickeau            try {
1114cadd4f8SNickeau                $expirationDate = Cron::getDate($cacheExpirationFrequency);
112*04fd306cSNickeau            } catch (ExceptionBadSyntax $e) {
113*04fd306cSNickeau                LogUtility::error("The cron expression ($cacheExpirationFrequency) of the page ($page) is not a valid cron expression");
114*04fd306cSNickeau                return false;
11537748cd8SNickeau            }
116*04fd306cSNickeau        }
117*04fd306cSNickeau        $cacheExpirationDateMeta->setValue($expirationDate);
1184cadd4f8SNickeau
1194cadd4f8SNickeau        $actualDate = new DateTime();
1204cadd4f8SNickeau        if ($expirationDate > $actualDate) {
1214cadd4f8SNickeau            $this->slotsExpiration[$pageId] = false;
1224cadd4f8SNickeau            return false;
12337748cd8SNickeau        }
12437748cd8SNickeau
1254cadd4f8SNickeau        $this->slotsExpiration[$pageId] = true;
1264cadd4f8SNickeau        return true;
127c3437056SNickeau
128c3437056SNickeau    }
12937748cd8SNickeau
13037748cd8SNickeau}
131