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