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