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