1<?php 2 3 4namespace ComboStrap; 5 6 7use DateTime; 8 9/** 10 * Class CacheManager 11 * @package ComboStrap 12 * 13 * The cache manager handles all things cache 14 * This is just another namespace extension of {@link ExecutionContext} 15 * to not have all function in the same place 16 * 17 * Except for the cache dependencies of a {@link FetcherMarkup::getOutputCacheDependencies() Markup} 18 */ 19class CacheManager 20{ 21 22 23 const CACHE_DELETION = "deletion"; 24 const CACHE_CREATION = "creation"; 25 26 27 /** 28 * The list of cache runtimes dependencies by slot {@link MarkupCacheDependencies} 29 */ 30 private array $slotCacheDependencies = []; 31 32 /** 33 * The list of cache results slot {@link CacheResults} 34 */ 35 private array $slotCacheResults = []; 36 37 /** 38 * @var array hold the result for slot cache expiration 39 */ 40 private array $slotsExpiration = []; 41 42 43 private ExecutionContext $executionContext; 44 45 public function __construct(ExecutionContext $executionContext) 46 { 47 $this->executionContext = $executionContext; 48 } 49 50 51 /** 52 * @return CacheManager 53 * @deprecated use the {@link ExecutionContext::getCacheManager()} instead otherwise you may mix context run 54 */ 55 public static function getFromContextExecution(): CacheManager 56 { 57 58 return ExecutionContext::getActualOrCreateFromEnv()->getCacheManager(); 59 60 } 61 62 63 64 public function &getCacheResultsForSlot(string $id): CacheResults 65 { 66 $cacheManagerForSlot = &$this->slotCacheResults[$id]; 67 if ($cacheManagerForSlot === null) { 68 $cacheManagerForSlot = new CacheResults($id); 69 $this->slotCacheResults[$id] = $cacheManagerForSlot; 70 } 71 return $cacheManagerForSlot; 72 } 73 74 /** 75 * @return CacheResults[] - null if the page does not exists 76 */ 77 public function getCacheResults(): array 78 { 79 return $this->slotCacheResults; 80 } 81 82 /** 83 */ 84 public function shouldSlotExpire($pageId): bool 85 { 86 87 /** 88 * Because of the recursive nature of rendering 89 * inside dokuwiki, we just return a result for 90 * the first call to the function 91 * 92 */ 93 if (isset($this->slotsExpiration[$pageId])) { 94 return false; 95 } 96 97 $page = MarkupPath::createMarkupFromId($pageId); 98 try { 99 $cacheExpirationFrequency = CacheExpirationFrequency::createForPage($page) 100 ->getValue(); 101 } catch (ExceptionNotFound $e) { 102 $this->slotsExpiration[$pageId] = false; 103 return false; 104 } 105 106 $cacheExpirationDateMeta = CacheExpirationDate::createForPage($page); 107 try { 108 $expirationDate = $cacheExpirationDateMeta->getValue(); 109 } catch (ExceptionNotFound $e) { 110 try { 111 $expirationDate = Cron::getDate($cacheExpirationFrequency); 112 } catch (ExceptionBadSyntax $e) { 113 LogUtility::error("The cron expression ($cacheExpirationFrequency) of the page ($page) is not a valid cron expression"); 114 return false; 115 } 116 } 117 $cacheExpirationDateMeta->setValue($expirationDate); 118 119 $actualDate = new DateTime(); 120 if ($expirationDate > $actualDate) { 121 $this->slotsExpiration[$pageId] = false; 122 return false; 123 } 124 125 $this->slotsExpiration[$pageId] = true; 126 return true; 127 128 } 129 130} 131