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