1<?php 2 3use ComboStrap\CacheExpirationDate; 4use ComboStrap\CacheManager; 5use ComboStrap\CacheMedia; 6use ComboStrap\CacheMenuItem; 7use ComboStrap\CacheReportHtmlDataBlockArray; 8use ComboStrap\Cron; 9use ComboStrap\ExceptionCombo; 10use ComboStrap\File; 11use ComboStrap\Http; 12use ComboStrap\Identity; 13use ComboStrap\Iso8601Date; 14use ComboStrap\LogUtility; 15use ComboStrap\MetadataDokuWikiStore; 16use ComboStrap\Page; 17use ComboStrap\PageDescription; 18use ComboStrap\PageH1; 19use ComboStrap\PageTitle; 20use ComboStrap\PluginUtility; 21use ComboStrap\ResourceName; 22use ComboStrap\Site; 23use dokuwiki\Cache\CacheRenderer; 24 25require_once(__DIR__ . '/../ComboStrap/PluginUtility.php'); 26 27/** 28 * Can we use the parser cache 29 * 30 * 31 * 32 */ 33class action_plugin_combo_cache extends DokuWiki_Action_Plugin 34{ 35 36 37 38 const CANONICAL = "cache"; 39 const STATIC_SCRIPT_NAMES = ["/lib/exe/jquery.php", "/lib/exe/js.php", "/lib/exe/css.php"]; 40 41 42 43 44 /** 45 * @param Doku_Event_Handler $controller 46 */ 47 function register(Doku_Event_Handler $controller) 48 { 49 50 /** 51 * Create a {@link \ComboStrap\CacheResult} 52 */ 53 $controller->register_hook('PARSER_CACHE_USE', 'AFTER', $this, 'createCacheResult', array()); 54 55 56 /** 57 * To add the cache result in the HTML 58 */ 59 $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'addCacheLogHtmlDataBlock', array()); 60 61 62 /** 63 * To delete the VARY on css.php, jquery.php, js.php 64 */ 65 $controller->register_hook('INIT_LANG_LOAD', 'BEFORE', $this, 'deleteVaryFromStaticGeneratedResources', array()); 66 67 68 /** 69 * Add a icon in the page tools menu 70 * https://www.dokuwiki.org/devel:event:menu_items_assembly 71 */ 72 $controller->register_hook('MENU_ITEMS_ASSEMBLY', 'AFTER', $this, 'addMenuItem'); 73 74 } 75 76 /** 77 * 78 * @param Doku_Event $event 79 * @param $params 80 */ 81 function createCacheResult(Doku_Event $event, $params) 82 { 83 84 /** 85 * To log the cache used by bar 86 * @var \dokuwiki\Cache\CacheParser $data 87 */ 88 $data = $event->data; 89 $slotId = $data->page; 90 $cacheReporter = CacheManager::getOrCreate()->getCacheResultsForSlot($slotId); 91 $cacheReporter->setData($event); 92 93 94 } 95 96 97 /** 98 * Add cache data to the rendered html page 99 * @param Doku_Event $event 100 * @param $params 101 */ 102 function addCacheLogHtmlDataBlock(Doku_Event $event, $params) 103 { 104 105 if(!PluginUtility::isRenderingRequestedPageProcess()){ 106 return; 107 } 108 $cacheSlotResults = CacheReportHtmlDataBlockArray::getFromRuntime(); 109 $cacheJson = \ComboStrap\Json::createFromArray($cacheSlotResults); 110 111 if (PluginUtility::isDevOrTest()) { 112 $result = $cacheJson->toPrettyJsonString(); 113 } else { 114 $result = $cacheJson->toMinifiedJsonString(); 115 } 116 117 $event->data["script"][] = array( 118 "type" => CacheReportHtmlDataBlockArray::APPLICATION_COMBO_CACHE_JSON, 119 "_data" => $result, 120 ); 121 122 123 } 124 125 126 127 /** 128 * Delete the Vary header 129 * @param Doku_Event $event 130 * @param $params 131 */ 132 public static function deleteVaryFromStaticGeneratedResources(Doku_Event $event, $params) 133 { 134 135 $script = $_SERVER["SCRIPT_NAME"]; 136 if (in_array($script, self::STATIC_SCRIPT_NAMES)) { 137 // To be extra sure, they must have the buster key 138 if (isset($_REQUEST[CacheMedia::CACHE_BUSTER_KEY])) { 139 self::deleteVaryHeader(); 140 } 141 } 142 143 } 144 145 /** 146 * 147 * No Vary: Cookie 148 * Introduced at 149 * https://github.com/splitbrain/dokuwiki/issues/1594 150 * But cache problem at: 151 * https://github.com/splitbrain/dokuwiki/issues/2520 152 * 153 */ 154 public static function deleteVaryHeader(): void 155 { 156 if (PluginUtility::getConfValue(action_plugin_combo_staticresource::CONF_STATIC_CACHE_ENABLED, 1)) { 157 Http::removeHeaderIfPresent("Vary"); 158 } 159 } 160 161 162 163 164 function addMenuItem(Doku_Event $event, $param) 165 { 166 167 /** 168 * The `view` property defines the menu that is currently built 169 * https://www.dokuwiki.org/devel:menus 170 * If this is not the page menu, return 171 */ 172 if ($event->data['view'] != 'page') return; 173 174 global $INFO; 175 if (!$INFO['exists']) { 176 return; 177 } 178 /** 179 * Cache is for manager 180 */ 181 if (!Identity::isManager()) { 182 return; 183 } 184 array_splice($event->data['items'], -1, 0, array(new CacheMenuItem())); 185 186 187 } 188 189} 190