1<?php 2 3use dokuwiki\plugin\struct\meta\Assignments; 4use dokuwiki\plugin\struct\meta\SearchConfig; 5use dokuwiki\plugin\struct\meta\SearchConfigParameters; 6use dokuwiki\plugin\structat\meta\SearchConfigAtParameters; 7 8/** 9 * Handle caching of pages containing struct aggregations 10 */ 11class action_plugin_structat_cache extends DokuWiki_Action_Plugin 12{ 13 14 /** 15 * Registers a callback function for a given event 16 * 17 * @param Doku_Event_Handler $controller DokuWiki's event controller object 18 * @return void 19 */ 20 public function register(Doku_Event_Handler $controller) 21 { 22 $controller->register_hook('PARSER_CACHE_USE', 'BEFORE', $this, 'handleCacheAggregation', null, 1); 23 $controller->register_hook('PARSER_CACHE_USE', 'AFTER', $this, 'handleCacheDynamic', null, 1); 24 } 25 26 /** 27 * For pages containing an aggregation, add the last modified date of the database itself 28 * to the cache dependencies 29 * 30 * @param Doku_Event $event event object by reference 31 * @param mixed $param [the parameters passed as fifth argument to register_hook() when this 32 * handler was registered] 33 * @return bool 34 */ 35 public function handleCacheAggregation(Doku_Event $event, $param) 36 { 37 global $INPUT; 38 39 /** @var \cache_parser $cache */ 40 $cache = $event->data; 41 if ($cache->mode != 'xhtml') return true; 42 if (!$cache->page) return true; // not a page cache 43 44 $meta = p_get_metadata($cache->page, 'plugin struct'); 45 if (isset($meta['hasaggregation'])) { 46 // dynamic renders should never overwrite the default page cache 47 // we need this in additon to handle_cache_dynamic() below because we can only 48 // influence if a cache is used, not that it will be written 49 if ( 50 $INPUT->has(SearchConfigAtParameters::$PARAM_AT) 51 ) { 52 // check if we have an user 53 $user_key = ''; 54 if ($meta['hasaggregation'] & SearchConfig::$CACHE_USER) { 55 //remove user part 56 $user_key = ';' . $INPUT->server->str('REMOTE_USER'); 57 $cache->key = substr($cache->key, 0, -strlen($user_key)); 58 } 59 // not dynamic yet 60 if (substr($cache->key, -strlen('dynamic')) != 'dynamic') { 61 $cache->key .= 'dynamic'; 62 } 63 $cache->key .= $user_key; 64 } 65 66 // rebuild cachename 67 $cache->cache = getCacheName($cache->key, $cache->ext); 68 } 69 70 return true; 71 } 72 73 /** 74 * Disable cache when dymanic parameters are present 75 * 76 * @param Doku_Event $event event object by reference 77 * @param mixed $param [the parameters passed as fifth argument to register_hook() when this 78 * handler was registered] 79 * @return bool 80 */ 81 public function handleCacheDynamic(Doku_Event $event, $param) 82 { 83 /** @var \cache_parser $cache */ 84 $cache = $event->data; 85 if ($cache->mode != 'xhtml') return true; 86 if (!$cache->page) return true; // not a page cache 87 global $INPUT; 88 89 // disable cache use when one of these parameters is present 90 foreach ( 91 array( 92 SearchConfigAtParameters::$PARAM_AT 93 ) as $key 94 ) { 95 if ($INPUT->has($key)) { 96 $event->result = false; 97 return true; 98 } 99 } 100 101 return true; 102 } 103} 104