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