xref: /plugin/struct/action/cache.php (revision d6d97f6064c3b0f90310be8341edc9585520ee54)
1dbe5bc9dSAndreas Gohr<?php
2*d6d97f60SAnna 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 */
10*d6d97f60SAnna Dabrowskaclass action_plugin_struct_cache extends DokuWiki_Action_Plugin
11*d6d97f60SAnna 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     */
19*d6d97f60SAnna Dabrowska    public function register(Doku_Event_Handler $controller)
20*d6d97f60SAnna Dabrowska    {
21ae5c46faSAndreas Gohr        $controller->register_hook('PARSER_CACHE_USE', 'BEFORE', $this, 'handle_cache_schemachange');
22dbe5bc9dSAndreas Gohr        $controller->register_hook('PARSER_CACHE_USE', 'BEFORE', $this, 'handle_cache_aggregation');
23dbe5bc9dSAndreas Gohr        $controller->register_hook('PARSER_CACHE_USE', 'AFTER', $this, 'handle_cache_dynamic');
24dbe5bc9dSAndreas Gohr    }
25dbe5bc9dSAndreas Gohr
26dbe5bc9dSAndreas Gohr    /**
27ae5c46faSAndreas Gohr     * @return string the refresh file
28ae5c46faSAndreas Gohr     */
29*d6d97f60SAnna Dabrowska    public static function getSchemaRefreshFile()
30*d6d97f60SAnna 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*d6d97f60SAnna Dabrowska    public function handle_cache_schemachange(Doku_Event $event, $param)
45*d6d97f60SAnna 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*d6d97f60SAnna Dabrowska    public function handle_cache_aggregation(Doku_Event $event, $param)
68*d6d97f60SAnna 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*d6d97f60SAnna Dabrowska    public function handle_cache_dynamic(Doku_Event $event, $param)
125*d6d97f60SAnna 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
133*d6d97f60SAnna Dabrowska        foreach (
134*d6d97f60SAnna Dabrowska            array(
13553ed3125SAndreas Gohr                    SearchConfigParameters::$PARAM_FILTER,
13653ed3125SAndreas Gohr                    SearchConfigParameters::$PARAM_OFFSET,
13753ed3125SAndreas Gohr                    SearchConfigParameters::$PARAM_SORT
138*d6d97f60SAnna Dabrowska                ) as $key
139*d6d97f60SAnna 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