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