137748cd8SNickeau<?php 237748cd8SNickeau 337748cd8SNickeau 437748cd8SNickeaunamespace ComboStrap; 537748cd8SNickeau 637748cd8SNickeau 737748cd8SNickeauuse dokuwiki\Cache\CacheParser; 837748cd8SNickeau 937748cd8SNickeauclass CacheManager 1037748cd8SNickeau{ 1137748cd8SNickeau 1237748cd8SNickeau const RESULT_STATUS = 'result'; 1337748cd8SNickeau const DATE_MODIFIED = 'ftime'; 14*c3437056SNickeau public const APPLICATION_COMBO_CACHE_JSON = "application/combo+cache+json"; 1537748cd8SNickeau 1637748cd8SNickeau /** 17*c3437056SNickeau * @var CacheManager 1837748cd8SNickeau */ 19*c3437056SNickeau private static $cacheManager; 20*c3437056SNickeau 21*c3437056SNickeau /** 22*c3437056SNickeau * Just an utility variable to tracks the cache result of each slot 23*c3437056SNickeau * @var array the processed slot by: 24*c3437056SNickeau * * requested page id, (to avoid inconsistency on multiple page run in one test) 25*c3437056SNickeau * * slot id 26*c3437056SNickeau */ 27*c3437056SNickeau private $cacheResults = array(); 2837748cd8SNickeau 2937748cd8SNickeau 3037748cd8SNickeau /** 3137748cd8SNickeau * @return CacheManager 3237748cd8SNickeau */ 33*c3437056SNickeau public static function getOrCreate(): CacheManager 3437748cd8SNickeau { 35*c3437056SNickeau if (self::$cacheManager === null) { 36*c3437056SNickeau self::$cacheManager = new CacheManager(); 3737748cd8SNickeau } 38*c3437056SNickeau return self::$cacheManager; 3937748cd8SNickeau } 4037748cd8SNickeau 4137748cd8SNickeau 4237748cd8SNickeau /** 4337748cd8SNickeau * In test, we may run more than once 4437748cd8SNickeau * This function delete the cache manager 4537748cd8SNickeau * and is called when Dokuwiki close (ie {@link \action_plugin_combo_cache::close()}) 4637748cd8SNickeau */ 47*c3437056SNickeau public static function reset() 4837748cd8SNickeau { 4937748cd8SNickeau 50*c3437056SNickeau self::$cacheManager = null; 5137748cd8SNickeau 5237748cd8SNickeau } 5337748cd8SNickeau 5437748cd8SNickeau /** 55*c3437056SNickeau * Keep track of the parsed slot (ie page in page) 56*c3437056SNickeau * @param $slotId 5737748cd8SNickeau * @param $result 5837748cd8SNickeau * @param CacheParser $cacheParser 5937748cd8SNickeau */ 60*c3437056SNickeau public function addSlotForRequestedPage($slotId, $result, CacheParser $cacheParser) 6137748cd8SNickeau { 62*c3437056SNickeau 63*c3437056SNickeau $requestedPageSlotResults = &$this->getCacheSlotResultsForRequestedPage(); 64*c3437056SNickeau 65*c3437056SNickeau 66*c3437056SNickeau if (!isset($requestedPageSlotResults[$slotId])) { 67*c3437056SNickeau $requestedPageSlotResults[$slotId] = []; 6837748cd8SNickeau } 69*c3437056SNickeau 7037748cd8SNickeau /** 7137748cd8SNickeau * Metadata and other rendering may occurs 7237748cd8SNickeau * recursively in one request 7337748cd8SNickeau * 7437748cd8SNickeau * We record only the first one because the second call one will use the first 7537748cd8SNickeau * one 7637748cd8SNickeau */ 77*c3437056SNickeau if (!isset($requestedPageSlotResults[$slotId][$cacheParser->mode])) { 7837748cd8SNickeau $date = null; 7937748cd8SNickeau if (file_exists($cacheParser->cache)) { 8037748cd8SNickeau $date = Iso8601Date::createFromTimestamp(filemtime($cacheParser->cache))->getDateTime(); 8137748cd8SNickeau } 82*c3437056SNickeau $requestedPageSlotResults[$slotId][$cacheParser->mode] = [ 8337748cd8SNickeau self::RESULT_STATUS => $result, 8437748cd8SNickeau self::DATE_MODIFIED => $date 8537748cd8SNickeau ]; 8637748cd8SNickeau } 8737748cd8SNickeau 8837748cd8SNickeau } 8937748cd8SNickeau 90*c3437056SNickeau public function getXhtmlCacheSlotResultsForRequestedPage(): array 9137748cd8SNickeau { 92*c3437056SNickeau $cacheSlotResultsForRequestedPage = $this->getCacheSlotResultsForRequestedPage(); 93*c3437056SNickeau if ($cacheSlotResultsForRequestedPage === null) { 94*c3437056SNickeau return []; 95*c3437056SNickeau } 9637748cd8SNickeau $xhtmlRenderResult = []; 97*c3437056SNickeau foreach ($cacheSlotResultsForRequestedPage as $slotId => $modes) { 9837748cd8SNickeau foreach ($modes as $mode => $values) { 9937748cd8SNickeau if ($mode === "xhtml") { 100*c3437056SNickeau $xhtmlRenderResult[$slotId] = $values[self::RESULT_STATUS]; 10137748cd8SNickeau } 10237748cd8SNickeau } 10337748cd8SNickeau } 10437748cd8SNickeau return $xhtmlRenderResult; 10537748cd8SNickeau } 10637748cd8SNickeau 107*c3437056SNickeau private function &getCacheSlotResultsForRequestedPage(): ?array 10837748cd8SNickeau { 109*c3437056SNickeau $requestedPage = $this->getRequestedPage(); 110*c3437056SNickeau $requestedPageSlotResults = &$this->cacheResults[$requestedPage]; 111*c3437056SNickeau if (!isset($requestedPageSlotResults)) { 112*c3437056SNickeau $requestedPageSlotResults = []; 113*c3437056SNickeau } 114*c3437056SNickeau return $requestedPageSlotResults; 11537748cd8SNickeau } 11637748cd8SNickeau 117*c3437056SNickeau public function isCacheLogPresentForSlot($slotId, $mode): bool 11837748cd8SNickeau { 119*c3437056SNickeau $cacheSlotResultsForRequestedPage = $this->getCacheSlotResultsForRequestedPage(); 120*c3437056SNickeau return isset($cacheSlotResultsForRequestedPage[$slotId][$mode]); 121*c3437056SNickeau } 122*c3437056SNickeau 123*c3437056SNickeau 124*c3437056SNickeau /** 125*c3437056SNickeau * @return array - a array that will be transformed as json HTML data block 126*c3437056SNickeau * to be included in a HTML page 127*c3437056SNickeau */ 128*c3437056SNickeau public function getCacheSlotResultsAsHtmlDataBlockArray(): array 129*c3437056SNickeau { 130*c3437056SNickeau $htmlDataBlock = []; 131*c3437056SNickeau $cacheSlotResultsForRequestedPage = $this->getCacheSlotResultsForRequestedPage(); 132*c3437056SNickeau if ($cacheSlotResultsForRequestedPage === null) { 133*c3437056SNickeau LogUtility::msg("No page slot results were found"); 134*c3437056SNickeau return []; 135*c3437056SNickeau } 136*c3437056SNickeau foreach ($cacheSlotResultsForRequestedPage as $pageId => $resultByFormat) { 137*c3437056SNickeau foreach ($resultByFormat as $format => $result) { 138*c3437056SNickeau $modifiedDate = $result[self::DATE_MODIFIED]; 139*c3437056SNickeau if ($modifiedDate !== null) { 140*c3437056SNickeau $modifiedDate = Iso8601Date::createFromDateTime($modifiedDate)->toString(); 141*c3437056SNickeau } 142*c3437056SNickeau $htmlDataBlock[$pageId][$format] = [ 143*c3437056SNickeau self::RESULT_STATUS => $result[self::RESULT_STATUS], 144*c3437056SNickeau "mtime" => $modifiedDate 145*c3437056SNickeau ]; 146*c3437056SNickeau } 147*c3437056SNickeau 148*c3437056SNickeau } 149*c3437056SNickeau return $htmlDataBlock; 150*c3437056SNickeau } 151*c3437056SNickeau 152*c3437056SNickeau private function getRequestedPage() 153*c3437056SNickeau { 154*c3437056SNickeau global $_REQUEST; 155*c3437056SNickeau $requestedPage = $_REQUEST[DokuwikiId::DOKUWIKI_ID_ATTRIBUTE]; 156*c3437056SNickeau 157*c3437056SNickeau if ($requestedPage !== null) { 158*c3437056SNickeau return $requestedPage; 159*c3437056SNickeau } 160*c3437056SNickeau 161*c3437056SNickeau /** 162*c3437056SNickeau * We are not on a HTTP request 163*c3437056SNickeau * but may be on a {@link Page::renderMetadataAndFlush() metadata rendering request} 164*c3437056SNickeau */ 165*c3437056SNickeau global $ID; 166*c3437056SNickeau if ($ID !== null) { 167*c3437056SNickeau return $ID; 168*c3437056SNickeau } 169*c3437056SNickeau 170*c3437056SNickeau if(PluginUtility::isTest()) { 171*c3437056SNickeau /** 172*c3437056SNickeau * {@link p_get_metadata()} check the cache and is used 173*c3437056SNickeau * also in several place such as {@link feed.php} 174*c3437056SNickeau * where we don't have any influence 175*c3437056SNickeau */ 176*c3437056SNickeau LogUtility::msg("The requested page should be known to register a page cache result"); 177*c3437056SNickeau } 178*c3437056SNickeau return "unknown"; 179*c3437056SNickeau } 180*c3437056SNickeau 181*c3437056SNickeau public function isEmpty(): bool 182*c3437056SNickeau { 183*c3437056SNickeau return sizeof($this->cacheResults) === 0; 18437748cd8SNickeau } 18537748cd8SNickeau 18637748cd8SNickeau 18737748cd8SNickeau} 188