xref: /plugin/struct/action/cache.php (revision ae5c46fa8934a9eea411a0b8490529f375684ae2)
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