1dbe5bc9dSAndreas Gohr<?php 2d6d97f60SAnna Dabrowska 3ae5c46faSAndreas Gohruse dokuwiki\plugin\struct\meta\Assignments; 4ba766201SAndreas Gohruse dokuwiki\plugin\struct\meta\SearchConfig; 5ba766201SAndreas Gohruse dokuwiki\plugin\struct\meta\SearchConfigParameters; 6dbe5bc9dSAndreas Gohr 7dbe5bc9dSAndreas Gohr/** 8dbe5bc9dSAndreas Gohr * Handle caching of pages containing struct aggregations 9dbe5bc9dSAndreas Gohr */ 10d6d97f60SAnna Dabrowskaclass action_plugin_struct_cache extends DokuWiki_Action_Plugin 11d6d97f60SAnna Dabrowska{ 12dbe5bc9dSAndreas Gohr /** 13dbe5bc9dSAndreas Gohr * Registers a callback function for a given event 14dbe5bc9dSAndreas Gohr * 15dbe5bc9dSAndreas Gohr * @param Doku_Event_Handler $controller DokuWiki's event controller object 16dbe5bc9dSAndreas Gohr * @return void 17dbe5bc9dSAndreas Gohr */ 18d6d97f60SAnna Dabrowska public function register(Doku_Event_Handler $controller) 19d6d97f60SAnna Dabrowska { 20748e747fSAnna Dabrowska $controller->register_hook('PARSER_CACHE_USE', 'BEFORE', $this, 'handleCacheSchemachange'); 21748e747fSAnna Dabrowska $controller->register_hook('PARSER_CACHE_USE', 'BEFORE', $this, 'handleCacheAggregation'); 22748e747fSAnna Dabrowska $controller->register_hook('PARSER_CACHE_USE', 'AFTER', $this, 'handleCacheDynamic'); 23dbe5bc9dSAndreas Gohr } 24dbe5bc9dSAndreas Gohr 25dbe5bc9dSAndreas Gohr /** 26ae5c46faSAndreas Gohr * @return string the refresh file 27ae5c46faSAndreas Gohr */ 28d6d97f60SAnna Dabrowska public static function getSchemaRefreshFile() 29d6d97f60SAnna Dabrowska { 30ae5c46faSAndreas Gohr global $conf; 31ae5c46faSAndreas Gohr return $conf['cachedir'] . '/struct.schemarefresh'; 32ae5c46faSAndreas Gohr } 33ae5c46faSAndreas Gohr 34ae5c46faSAndreas Gohr /** 35ae5c46faSAndreas Gohr * For pages potentially containing schema data, refresh the cache when schema data has been 36ae5c46faSAndreas Gohr * updated 37ae5c46faSAndreas Gohr * 38ae5c46faSAndreas Gohr * @param Doku_Event $event event object by reference 39ae5c46faSAndreas Gohr * @param mixed $param [the parameters passed as fifth argument to register_hook() when this 40ae5c46faSAndreas Gohr * handler was registered] 41ae5c46faSAndreas Gohr * @return bool 42ae5c46faSAndreas Gohr */ 43748e747fSAnna Dabrowska public function handleCacheSchemachange(Doku_Event $event, $param) 44d6d97f60SAnna Dabrowska { 45ae5c46faSAndreas Gohr /** @var \cache_parser $cache */ 46ae5c46faSAndreas Gohr $cache = $event->data; 47ae5c46faSAndreas Gohr if ($cache->mode != 'xhtml') return true; 48ae5c46faSAndreas Gohr if (!$cache->page) return true; // not a page cache 49ae5c46faSAndreas Gohr 50ae5c46faSAndreas Gohr $assignments = Assignments::getInstance(); 51ae5c46faSAndreas Gohr if (!$assignments->getPageAssignments($cache->page)) return true; // no struct here 52ae5c46faSAndreas Gohr 53ae5c46faSAndreas Gohr $cache->depends['files'][] = self::getSchemaRefreshFile(); 54ae5c46faSAndreas Gohr return true; 55ae5c46faSAndreas Gohr } 56ae5c46faSAndreas Gohr 57ae5c46faSAndreas Gohr /** 58dbe5bc9dSAndreas Gohr * For pages containing an aggregation, add the last modified date of the database itself 59dbe5bc9dSAndreas Gohr * to the cache dependencies 60dbe5bc9dSAndreas Gohr * 61dbe5bc9dSAndreas Gohr * @param Doku_Event $event event object by reference 62dbe5bc9dSAndreas Gohr * @param mixed $param [the parameters passed as fifth argument to register_hook() when this 63dbe5bc9dSAndreas Gohr * handler was registered] 64dbe5bc9dSAndreas Gohr * @return bool 65dbe5bc9dSAndreas Gohr */ 66748e747fSAnna Dabrowska public function handleCacheAggregation(Doku_Event $event, $param) 67d6d97f60SAnna Dabrowska { 6816b7d914SAndreas Gohr global $INPUT; 6916b7d914SAndreas Gohr 70dbe5bc9dSAndreas Gohr /** @var \cache_parser $cache */ 71dbe5bc9dSAndreas Gohr $cache = $event->data; 72dbe5bc9dSAndreas Gohr if ($cache->mode != 'xhtml') return true; 73dbe5bc9dSAndreas Gohr if (!$cache->page) return true; // not a page cache 74dbe5bc9dSAndreas Gohr 75dbe5bc9dSAndreas Gohr $meta = p_get_metadata($cache->page, 'plugin struct'); 76dbe5bc9dSAndreas Gohr if (isset($meta['hasaggregation'])) { 77dbe5bc9dSAndreas Gohr /** @var helper_plugin_struct_db $db */ 78dbe5bc9dSAndreas Gohr $db = plugin_load('helper', 'struct_db'); 791dc771ecSAndreas Gohr // cache depends on last database save 807cbcfbdbSAndreas Gohr $sqlite = $db->getDB(false); 817cbcfbdbSAndreas Gohr if ($sqlite) { 82*79b29326SAnna Dabrowska $cache->depends['files'][] = $sqlite->getDbFile(); 837cbcfbdbSAndreas Gohr } 8416b7d914SAndreas Gohr 851dc771ecSAndreas Gohr // dynamic renders should never overwrite the default page cache 861dc771ecSAndreas Gohr // we need this in additon to handle_cache_dynamic() below because we can only 871dc771ecSAndreas Gohr // influence if a cache is used, not that it will be written 881dc771ecSAndreas Gohr if ( 891dc771ecSAndreas Gohr $INPUT->has(SearchConfigParameters::$PARAM_FILTER) || 901dc771ecSAndreas Gohr $INPUT->has(SearchConfigParameters::$PARAM_OFFSET) || 911dc771ecSAndreas Gohr $INPUT->has(SearchConfigParameters::$PARAM_SORT) 921dc771ecSAndreas Gohr ) { 931dc771ecSAndreas Gohr $cache->key .= 'dynamic'; 941dc771ecSAndreas Gohr } 951dc771ecSAndreas Gohr 9616b7d914SAndreas Gohr // cache depends on today's date 9716b7d914SAndreas Gohr if ($meta['hasaggregation'] & SearchConfig::$CACHE_DATE) { 9816b7d914SAndreas Gohr $oldage = $cache->depends['age']; 9916b7d914SAndreas Gohr $newage = time() - mktime(0, 0, 1); // time since first second today 10016b7d914SAndreas Gohr $cache->depends['age'] = min($oldage, $newage); 10116b7d914SAndreas Gohr } 10216b7d914SAndreas Gohr 10316b7d914SAndreas Gohr // cache depends on current user 10416b7d914SAndreas Gohr if ($meta['hasaggregation'] & SearchConfig::$CACHE_USER) { 10516b7d914SAndreas Gohr $cache->key .= ';' . $INPUT->server->str('REMOTE_USER'); 10616b7d914SAndreas Gohr } 1071dc771ecSAndreas Gohr 1081dc771ecSAndreas Gohr // rebuild cachename 1091dc771ecSAndreas Gohr $cache->cache = getCacheName($cache->key, $cache->ext); 110dbe5bc9dSAndreas Gohr } 111dbe5bc9dSAndreas Gohr 112dbe5bc9dSAndreas Gohr return true; 113dbe5bc9dSAndreas Gohr } 114dbe5bc9dSAndreas Gohr 115dbe5bc9dSAndreas Gohr /** 116dbe5bc9dSAndreas Gohr * Disable cache when dymanic parameters are present 117dbe5bc9dSAndreas Gohr * 118dbe5bc9dSAndreas Gohr * @param Doku_Event $event event object by reference 119dbe5bc9dSAndreas Gohr * @param mixed $param [the parameters passed as fifth argument to register_hook() when this 120dbe5bc9dSAndreas Gohr * handler was registered] 121dbe5bc9dSAndreas Gohr * @return bool 122dbe5bc9dSAndreas Gohr */ 123748e747fSAnna Dabrowska public function handleCacheDynamic(Doku_Event $event, $param) 124d6d97f60SAnna Dabrowska { 125dbe5bc9dSAndreas Gohr /** @var \cache_parser $cache */ 126dbe5bc9dSAndreas Gohr $cache = $event->data; 127dbe5bc9dSAndreas Gohr if ($cache->mode != 'xhtml') return true; 128dbe5bc9dSAndreas Gohr if (!$cache->page) return true; // not a page cache 129dbe5bc9dSAndreas Gohr global $INPUT; 130dbe5bc9dSAndreas Gohr 131dbe5bc9dSAndreas Gohr // disable cache use when one of these parameters is present 132d6d97f60SAnna Dabrowska foreach ( 133d6d97f60SAnna Dabrowska array( 13453ed3125SAndreas Gohr SearchConfigParameters::$PARAM_FILTER, 13553ed3125SAndreas Gohr SearchConfigParameters::$PARAM_OFFSET, 13653ed3125SAndreas Gohr SearchConfigParameters::$PARAM_SORT 137d6d97f60SAnna Dabrowska ) as $key 138d6d97f60SAnna Dabrowska ) { 139dbe5bc9dSAndreas Gohr if ($INPUT->has($key)) { 140dbe5bc9dSAndreas Gohr $event->result = false; 141dbe5bc9dSAndreas Gohr return true; 142dbe5bc9dSAndreas Gohr } 143dbe5bc9dSAndreas Gohr } 144dbe5bc9dSAndreas Gohr 145dbe5bc9dSAndreas Gohr return true; 146dbe5bc9dSAndreas Gohr } 147dbe5bc9dSAndreas Gohr} 148