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 $sqlite = $db->getDB(false); 44 if($sqlite) { 45 $cache->depends['files'][] = $sqlite->getAdapter()->getDbFile(); 46 } 47 48 // dynamic renders should never overwrite the default page cache 49 // we need this in additon to handle_cache_dynamic() below because we can only 50 // influence if a cache is used, not that it will be written 51 if( 52 $INPUT->has(SearchConfigParameters::$PARAM_FILTER) || 53 $INPUT->has(SearchConfigParameters::$PARAM_OFFSET) || 54 $INPUT->has(SearchConfigParameters::$PARAM_SORT) 55 ) { 56 $cache->key .= 'dynamic'; 57 } 58 59 // cache depends on today's date 60 if($meta['hasaggregation'] & SearchConfig::$CACHE_DATE) { 61 $oldage = $cache->depends['age']; 62 $newage = time() - mktime(0, 0, 1); // time since first second today 63 $cache->depends['age'] = min($oldage, $newage); 64 } 65 66 // cache depends on current user 67 if($meta['hasaggregation'] & SearchConfig::$CACHE_USER) { 68 $cache->key .= ';'.$INPUT->server->str('REMOTE_USER'); 69 70 } 71 72 // rebuild cachename 73 $cache->cache = getCacheName($cache->key, $cache->ext); 74 } 75 76 return true; 77 } 78 79 /** 80 * Disable cache when dymanic parameters are present 81 * 82 * @param Doku_Event $event event object by reference 83 * @param mixed $param [the parameters passed as fifth argument to register_hook() when this 84 * handler was registered] 85 * @return bool 86 */ 87 public function handle_cache_dynamic(Doku_Event $event, $param) { 88 /** @var \cache_parser $cache */ 89 $cache = $event->data; 90 if($cache->mode != 'xhtml') return true; 91 if(!$cache->page) return true; // not a page cache 92 global $INPUT; 93 94 // disable cache use when one of these parameters is present 95 foreach(array( 96 SearchConfigParameters::$PARAM_FILTER, 97 SearchConfigParameters::$PARAM_OFFSET, 98 SearchConfigParameters::$PARAM_SORT 99 ) as $key) { 100 if($INPUT->has($key)) { 101 $event->result = false; 102 return true; 103 } 104 } 105 106 return true; 107 } 108 109} 110