1dbe5bc9dSAndreas Gohr<?php 2*ae5c46faSAndreas Gohruse dokuwiki\plugin\struct\meta\Assignments; 3ba766201SAndreas Gohruse dokuwiki\plugin\struct\meta\SearchConfig; 4ba766201SAndreas Gohruse dokuwiki\plugin\struct\meta\SearchConfigParameters; 5dbe5bc9dSAndreas Gohr 6dbe5bc9dSAndreas Gohr/** 7dbe5bc9dSAndreas Gohr * Handle caching of pages containing struct aggregations 8dbe5bc9dSAndreas Gohr */ 9dbe5bc9dSAndreas Gohrclass action_plugin_struct_cache extends DokuWiki_Action_Plugin { 10dbe5bc9dSAndreas Gohr 11dbe5bc9dSAndreas Gohr /** 12dbe5bc9dSAndreas Gohr * Registers a callback function for a given event 13dbe5bc9dSAndreas Gohr * 14dbe5bc9dSAndreas Gohr * @param Doku_Event_Handler $controller DokuWiki's event controller object 15dbe5bc9dSAndreas Gohr * @return void 16dbe5bc9dSAndreas Gohr */ 17dbe5bc9dSAndreas Gohr public function register(Doku_Event_Handler $controller) { 18*ae5c46faSAndreas Gohr $controller->register_hook('PARSER_CACHE_USE', 'BEFORE', $this, 'handle_cache_schemachange'); 19dbe5bc9dSAndreas Gohr $controller->register_hook('PARSER_CACHE_USE', 'BEFORE', $this, 'handle_cache_aggregation'); 20dbe5bc9dSAndreas Gohr $controller->register_hook('PARSER_CACHE_USE', 'AFTER', $this, 'handle_cache_dynamic'); 21dbe5bc9dSAndreas Gohr } 22dbe5bc9dSAndreas Gohr 23dbe5bc9dSAndreas Gohr /** 24*ae5c46faSAndreas Gohr * @return string the refresh file 25*ae5c46faSAndreas Gohr */ 26*ae5c46faSAndreas Gohr public static function getSchemaRefreshFile() { 27*ae5c46faSAndreas Gohr global $conf; 28*ae5c46faSAndreas Gohr return $conf['cachedir'] . '/struct.schemarefresh'; 29*ae5c46faSAndreas Gohr } 30*ae5c46faSAndreas Gohr 31*ae5c46faSAndreas Gohr /** 32*ae5c46faSAndreas Gohr * For pages potentially containing schema data, refresh the cache when schema data has been 33*ae5c46faSAndreas Gohr * updated 34*ae5c46faSAndreas Gohr * 35*ae5c46faSAndreas Gohr * @param Doku_Event $event event object by reference 36*ae5c46faSAndreas Gohr * @param mixed $param [the parameters passed as fifth argument to register_hook() when this 37*ae5c46faSAndreas Gohr * handler was registered] 38*ae5c46faSAndreas Gohr * @return bool 39*ae5c46faSAndreas Gohr */ 40*ae5c46faSAndreas Gohr public function handle_cache_schemachange(Doku_Event $event, $param) { 41*ae5c46faSAndreas Gohr /** @var \cache_parser $cache */ 42*ae5c46faSAndreas Gohr $cache = $event->data; 43*ae5c46faSAndreas Gohr if($cache->mode != 'xhtml') return true; 44*ae5c46faSAndreas Gohr if(!$cache->page) return true; // not a page cache 45*ae5c46faSAndreas Gohr 46*ae5c46faSAndreas Gohr $assignments = Assignments::getInstance(); 47*ae5c46faSAndreas Gohr if(!$assignments->getPageAssignments($cache->page)) return true; // no struct here 48*ae5c46faSAndreas Gohr 49*ae5c46faSAndreas Gohr $cache->depends['files'][] = self::getSchemaRefreshFile(); 50*ae5c46faSAndreas Gohr return true; 51*ae5c46faSAndreas Gohr } 52*ae5c46faSAndreas Gohr 53*ae5c46faSAndreas Gohr /** 54dbe5bc9dSAndreas Gohr * For pages containing an aggregation, add the last modified date of the database itself 55dbe5bc9dSAndreas Gohr * to the cache dependencies 56dbe5bc9dSAndreas Gohr * 57dbe5bc9dSAndreas Gohr * @param Doku_Event $event event object by reference 58dbe5bc9dSAndreas Gohr * @param mixed $param [the parameters passed as fifth argument to register_hook() when this 59dbe5bc9dSAndreas Gohr * handler was registered] 60dbe5bc9dSAndreas Gohr * @return bool 61dbe5bc9dSAndreas Gohr */ 62dbe5bc9dSAndreas Gohr public function handle_cache_aggregation(Doku_Event $event, $param) { 6316b7d914SAndreas Gohr global $INPUT; 6416b7d914SAndreas Gohr 65dbe5bc9dSAndreas Gohr /** @var \cache_parser $cache */ 66dbe5bc9dSAndreas Gohr $cache = $event->data; 67dbe5bc9dSAndreas Gohr if($cache->mode != 'xhtml') return true; 68dbe5bc9dSAndreas Gohr if(!$cache->page) return true; // not a page cache 69dbe5bc9dSAndreas Gohr 70dbe5bc9dSAndreas Gohr $meta = p_get_metadata($cache->page, 'plugin struct'); 71dbe5bc9dSAndreas Gohr if(isset($meta['hasaggregation'])) { 72dbe5bc9dSAndreas Gohr /** @var helper_plugin_struct_db $db */ 73dbe5bc9dSAndreas Gohr $db = plugin_load('helper', 'struct_db'); 741dc771ecSAndreas Gohr // cache depends on last database save 757cbcfbdbSAndreas Gohr $sqlite = $db->getDB(false); 767cbcfbdbSAndreas Gohr if($sqlite) { 777cbcfbdbSAndreas Gohr $cache->depends['files'][] = $sqlite->getAdapter()->getDbFile(); 787cbcfbdbSAndreas Gohr } 7916b7d914SAndreas Gohr 801dc771ecSAndreas Gohr // dynamic renders should never overwrite the default page cache 811dc771ecSAndreas Gohr // we need this in additon to handle_cache_dynamic() below because we can only 821dc771ecSAndreas Gohr // influence if a cache is used, not that it will be written 831dc771ecSAndreas Gohr if( 841dc771ecSAndreas Gohr $INPUT->has(SearchConfigParameters::$PARAM_FILTER) || 851dc771ecSAndreas Gohr $INPUT->has(SearchConfigParameters::$PARAM_OFFSET) || 861dc771ecSAndreas Gohr $INPUT->has(SearchConfigParameters::$PARAM_SORT) 871dc771ecSAndreas Gohr ) { 881dc771ecSAndreas Gohr $cache->key .= 'dynamic'; 891dc771ecSAndreas Gohr } 901dc771ecSAndreas Gohr 9116b7d914SAndreas Gohr // cache depends on today's date 9216b7d914SAndreas Gohr if($meta['hasaggregation'] & SearchConfig::$CACHE_DATE) { 9316b7d914SAndreas Gohr $oldage = $cache->depends['age']; 9416b7d914SAndreas Gohr $newage = time() - mktime(0, 0, 1); // time since first second today 9516b7d914SAndreas Gohr $cache->depends['age'] = min($oldage, $newage); 9616b7d914SAndreas Gohr } 9716b7d914SAndreas Gohr 9816b7d914SAndreas Gohr // cache depends on current user 9916b7d914SAndreas Gohr if($meta['hasaggregation'] & SearchConfig::$CACHE_USER) { 10016b7d914SAndreas Gohr $cache->key .= ';' . $INPUT->server->str('REMOTE_USER'); 1011dc771ecSAndreas Gohr 10216b7d914SAndreas Gohr } 1031dc771ecSAndreas Gohr 1041dc771ecSAndreas Gohr // rebuild cachename 1051dc771ecSAndreas Gohr $cache->cache = getCacheName($cache->key, $cache->ext); 106dbe5bc9dSAndreas Gohr } 107dbe5bc9dSAndreas Gohr 108dbe5bc9dSAndreas Gohr return true; 109dbe5bc9dSAndreas Gohr } 110dbe5bc9dSAndreas Gohr 111dbe5bc9dSAndreas Gohr /** 112dbe5bc9dSAndreas Gohr * Disable cache when dymanic parameters are present 113dbe5bc9dSAndreas Gohr * 114dbe5bc9dSAndreas Gohr * @param Doku_Event $event event object by reference 115dbe5bc9dSAndreas Gohr * @param mixed $param [the parameters passed as fifth argument to register_hook() when this 116dbe5bc9dSAndreas Gohr * handler was registered] 117dbe5bc9dSAndreas Gohr * @return bool 118dbe5bc9dSAndreas Gohr */ 119dbe5bc9dSAndreas Gohr public function handle_cache_dynamic(Doku_Event $event, $param) { 120dbe5bc9dSAndreas Gohr /** @var \cache_parser $cache */ 121dbe5bc9dSAndreas Gohr $cache = $event->data; 122dbe5bc9dSAndreas Gohr if($cache->mode != 'xhtml') return true; 123dbe5bc9dSAndreas Gohr if(!$cache->page) return true; // not a page cache 124dbe5bc9dSAndreas Gohr global $INPUT; 125dbe5bc9dSAndreas Gohr 126dbe5bc9dSAndreas Gohr // disable cache use when one of these parameters is present 12753ed3125SAndreas Gohr foreach(array( 12853ed3125SAndreas Gohr SearchConfigParameters::$PARAM_FILTER, 12953ed3125SAndreas Gohr SearchConfigParameters::$PARAM_OFFSET, 13053ed3125SAndreas Gohr SearchConfigParameters::$PARAM_SORT 13153ed3125SAndreas Gohr ) as $key) { 132dbe5bc9dSAndreas Gohr if($INPUT->has($key)) { 133dbe5bc9dSAndreas Gohr $event->result = false; 134dbe5bc9dSAndreas Gohr return true; 135dbe5bc9dSAndreas Gohr } 136dbe5bc9dSAndreas Gohr } 137dbe5bc9dSAndreas Gohr 138dbe5bc9dSAndreas Gohr return true; 139dbe5bc9dSAndreas Gohr } 140dbe5bc9dSAndreas Gohr 141dbe5bc9dSAndreas Gohr} 142