137748cd8SNickeau<?php 237748cd8SNickeau 337748cd8SNickeauuse ComboStrap\CacheManager; 44cadd4f8SNickeauuse ComboStrap\CacheMenuItem; 54cadd4f8SNickeauuse ComboStrap\CacheReportHtmlDataBlockArray; 6*04fd306cSNickeauuse ComboStrap\ExecutionContext; 71fa8c418SNickeauuse ComboStrap\Http; 84cadd4f8SNickeauuse ComboStrap\Identity; 9*04fd306cSNickeauuse ComboStrap\IFetcher; 1037748cd8SNickeauuse ComboStrap\PluginUtility; 11*04fd306cSNickeauuse ComboStrap\SiteConfig; 1237748cd8SNickeau 1337748cd8SNickeaurequire_once(__DIR__ . '/../ComboStrap/PluginUtility.php'); 1437748cd8SNickeau 1537748cd8SNickeau/** 1637748cd8SNickeau * Can we use the parser cache 174cadd4f8SNickeau * 184cadd4f8SNickeau * 194cadd4f8SNickeau * 2037748cd8SNickeau */ 2137748cd8SNickeauclass action_plugin_combo_cache extends DokuWiki_Action_Plugin 2237748cd8SNickeau{ 234cadd4f8SNickeau 2437748cd8SNickeau 251fa8c418SNickeau 261fa8c418SNickeau const CANONICAL = "cache"; 271fa8c418SNickeau const STATIC_SCRIPT_NAMES = ["/lib/exe/jquery.php", "/lib/exe/js.php", "/lib/exe/css.php"]; 281fa8c418SNickeau 29c3437056SNickeau 30c3437056SNickeau 31c3437056SNickeau 32c3437056SNickeau /** 3337748cd8SNickeau * @param Doku_Event_Handler $controller 3437748cd8SNickeau */ 3537748cd8SNickeau function register(Doku_Event_Handler $controller) 3637748cd8SNickeau { 3737748cd8SNickeau 3837748cd8SNickeau /** 394cadd4f8SNickeau * Create a {@link \ComboStrap\CacheResult} 4037748cd8SNickeau */ 414cadd4f8SNickeau $controller->register_hook('PARSER_CACHE_USE', 'AFTER', $this, 'createCacheResult', array()); 4237748cd8SNickeau 4337748cd8SNickeau 4437748cd8SNickeau /** 45c3437056SNickeau * To add the cache result in the HTML 461fa8c418SNickeau */ 47c3437056SNickeau $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'addCacheLogHtmlDataBlock', array()); 4837748cd8SNickeau 4937748cd8SNickeau 501fa8c418SNickeau /** 511fa8c418SNickeau * To delete the VARY on css.php, jquery.php, js.php 521fa8c418SNickeau */ 531fa8c418SNickeau $controller->register_hook('INIT_LANG_LOAD', 'BEFORE', $this, 'deleteVaryFromStaticGeneratedResources', array()); 541fa8c418SNickeau 554cadd4f8SNickeau 56c3437056SNickeau /** 574cadd4f8SNickeau * Add a icon in the page tools menu 584cadd4f8SNickeau * https://www.dokuwiki.org/devel:event:menu_items_assembly 59c3437056SNickeau */ 604cadd4f8SNickeau $controller->register_hook('MENU_ITEMS_ASSEMBLY', 'AFTER', $this, 'addMenuItem'); 611fa8c418SNickeau 6237748cd8SNickeau } 6337748cd8SNickeau 6437748cd8SNickeau /** 6537748cd8SNickeau * 6637748cd8SNickeau * @param Doku_Event $event 6737748cd8SNickeau * @param $params 6837748cd8SNickeau */ 694cadd4f8SNickeau function createCacheResult(Doku_Event $event, $params) 7037748cd8SNickeau { 7137748cd8SNickeau 7237748cd8SNickeau /** 7337748cd8SNickeau * To log the cache used by bar 7437748cd8SNickeau * @var \dokuwiki\Cache\CacheParser $data 7537748cd8SNickeau */ 7637748cd8SNickeau $data = $event->data; 77c3437056SNickeau $slotId = $data->page; 78*04fd306cSNickeau if(empty($slotId)){ 79*04fd306cSNickeau // on edit mode, the page is emtpy 80*04fd306cSNickeau return; 81*04fd306cSNickeau } 82*04fd306cSNickeau $cacheReporter = CacheManager::getFromContextExecution()->getCacheResultsForSlot($slotId); 834cadd4f8SNickeau $cacheReporter->setData($event); 8437748cd8SNickeau 8537748cd8SNickeau 8637748cd8SNickeau } 8737748cd8SNickeau 8837748cd8SNickeau 8937748cd8SNickeau /** 904cadd4f8SNickeau * Add cache data to the rendered html page 9137748cd8SNickeau * @param Doku_Event $event 9237748cd8SNickeau * @param $params 9337748cd8SNickeau */ 94c3437056SNickeau function addCacheLogHtmlDataBlock(Doku_Event $event, $params) 9537748cd8SNickeau { 9637748cd8SNickeau 97*04fd306cSNickeau $isPublic = ExecutionContext::getActualOrCreateFromEnv() 98*04fd306cSNickeau ->isPublicationAction(); 99*04fd306cSNickeau if(!$isPublic){ 1004cadd4f8SNickeau return; 1014cadd4f8SNickeau } 102*04fd306cSNickeau $cacheSlotResults = CacheReportHtmlDataBlockArray::getFromContext(); 103c3437056SNickeau $cacheJson = \ComboStrap\Json::createFromArray($cacheSlotResults); 10437748cd8SNickeau 105c3437056SNickeau if (PluginUtility::isDevOrTest()) { 106c3437056SNickeau $result = $cacheJson->toPrettyJsonString(); 10737748cd8SNickeau } else { 108c3437056SNickeau $result = $cacheJson->toMinifiedJsonString(); 10937748cd8SNickeau } 11037748cd8SNickeau 111c3437056SNickeau $event->data["script"][] = array( 1124cadd4f8SNickeau "type" => CacheReportHtmlDataBlockArray::APPLICATION_COMBO_CACHE_JSON, 113c3437056SNickeau "_data" => $result, 114c3437056SNickeau ); 11537748cd8SNickeau 1164cadd4f8SNickeau 11737748cd8SNickeau } 11837748cd8SNickeau 1191fa8c418SNickeau 1201fa8c418SNickeau 1211fa8c418SNickeau /** 1221fa8c418SNickeau * Delete the Vary header 1231fa8c418SNickeau * @param Doku_Event $event 1241fa8c418SNickeau * @param $params 1251fa8c418SNickeau */ 1261fa8c418SNickeau public static function deleteVaryFromStaticGeneratedResources(Doku_Event $event, $params) 1271fa8c418SNickeau { 1281fa8c418SNickeau 1291fa8c418SNickeau $script = $_SERVER["SCRIPT_NAME"]; 1301fa8c418SNickeau if (in_array($script, self::STATIC_SCRIPT_NAMES)) { 131c3437056SNickeau // To be extra sure, they must have the buster key 132*04fd306cSNickeau if (isset($_REQUEST[IFetcher::CACHE_BUSTER_KEY])) { 1331fa8c418SNickeau self::deleteVaryHeader(); 1341fa8c418SNickeau } 1351fa8c418SNickeau } 1361fa8c418SNickeau 1371fa8c418SNickeau } 1381fa8c418SNickeau 1391fa8c418SNickeau /** 1401fa8c418SNickeau * 1411fa8c418SNickeau * No Vary: Cookie 1421fa8c418SNickeau * Introduced at 1431fa8c418SNickeau * https://github.com/splitbrain/dokuwiki/issues/1594 1441fa8c418SNickeau * But cache problem at: 1451fa8c418SNickeau * https://github.com/splitbrain/dokuwiki/issues/2520 1461fa8c418SNickeau * 1471fa8c418SNickeau */ 1481fa8c418SNickeau public static function deleteVaryHeader(): void 1491fa8c418SNickeau { 150*04fd306cSNickeau if (SiteConfig::getConfValue(action_plugin_combo_staticresource::CONF_STATIC_CACHE_ENABLED, 1)) { 1511fa8c418SNickeau Http::removeHeaderIfPresent("Vary"); 1521fa8c418SNickeau } 1531fa8c418SNickeau } 1541fa8c418SNickeau 1554cadd4f8SNickeau 1564cadd4f8SNickeau 1574cadd4f8SNickeau 1584cadd4f8SNickeau function addMenuItem(Doku_Event $event, $param) 159c3437056SNickeau { 160c3437056SNickeau 161c3437056SNickeau /** 1624cadd4f8SNickeau * The `view` property defines the menu that is currently built 1634cadd4f8SNickeau * https://www.dokuwiki.org/devel:menus 1644cadd4f8SNickeau * If this is not the page menu, return 165c3437056SNickeau */ 1664cadd4f8SNickeau if ($event->data['view'] != 'page') return; 167c3437056SNickeau 1684cadd4f8SNickeau global $INFO; 1694cadd4f8SNickeau if (!$INFO['exists']) { 1704cadd4f8SNickeau return; 171c3437056SNickeau } 172c3437056SNickeau /** 1734cadd4f8SNickeau * Cache is for manager 174c3437056SNickeau */ 1754cadd4f8SNickeau if (!Identity::isManager()) { 1764cadd4f8SNickeau return; 177c3437056SNickeau } 1784cadd4f8SNickeau array_splice($event->data['items'], -1, 0, array(new CacheMenuItem())); 179c3437056SNickeau 180c3437056SNickeau 181c3437056SNickeau } 18237748cd8SNickeau 18337748cd8SNickeau} 184