xref: /template/strap/action/cache.php (revision 37748cd8654635afbeca80942126742f0f4cc346)
1<?php
2
3use ComboStrap\CacheManager;
4use ComboStrap\Iso8601Date;
5use ComboStrap\PluginUtility;
6
7require_once(__DIR__ . '/../ComboStrap/PluginUtility.php');
8
9/**
10 * Can we use the parser cache
11 */
12class action_plugin_combo_cache extends DokuWiki_Action_Plugin
13{
14    const COMBO_CACHE_PREFIX = "combo:cache:";
15
16    /**
17     * @param Doku_Event_Handler $controller
18     */
19    function register(Doku_Event_Handler $controller)
20    {
21
22        /**
23         * Log the cache usage and also
24         */
25        $controller->register_hook('PARSER_CACHE_USE', 'AFTER', $this, 'logCacheUsage', array());
26
27        $controller->register_hook('PARSER_CACHE_USE', 'BEFORE', $this, 'purgeIfNeeded', array());
28
29        /**
30         * To add the cache result in the header
31         */
32        $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'addMeta', array());
33
34        /**
35         * To reset the cache manager
36         * between two run in the test
37         */
38        $controller->register_hook('DOKUWIKI_DONE', 'BEFORE', $this, 'close', array());
39
40    }
41
42    /**
43     *
44     * @param Doku_Event $event
45     * @param $params
46     */
47    function logCacheUsage(Doku_Event $event, $params)
48    {
49
50        /**
51         * To log the cache used by bar
52         * @var \dokuwiki\Cache\CacheParser $data
53         */
54        $data = $event->data;
55        $result = $event->result;
56        $pageId = $data->page;
57        $cacheManager = PluginUtility::getCacheManager();
58        $cacheManager->addSlot($pageId, $result, $data);
59
60
61    }
62
63    /**
64     *
65     * @param Doku_Event $event
66     * @param $params
67     */
68    function purgeIfNeeded(Doku_Event $event, $params)
69    {
70
71        /**
72         * No cache for all mode
73         * (ie xhtml, instruction)
74         */
75        $data = &$event->data;
76        $pageId = $data->page;
77        /**
78         * Because of the recursive nature of rendering
79         * inside dokuwiki, we just handle the first
80         * rendering for a request.
81         *
82         * The first will be purged, the other one not
83         * because they can use the first one
84         */
85        if (!PluginUtility::getCacheManager()->isCacheLogPresent($pageId, $data->mode)) {
86            $expirationStringDate = p_get_metadata($pageId, CacheManager::DATE_CACHE_EXPIRATION_META_KEY, METADATA_DONT_RENDER);
87            if ($expirationStringDate !== null) {
88
89                $expirationDate = Iso8601Date::create($expirationStringDate)->getDateTime();
90                $actualDate = new DateTime();
91                if ($expirationDate < $actualDate) {
92                    /**
93                     * As seen in {@link Cache::makeDefaultCacheDecision()}
94                     * We request a purge
95                     */
96                    $data->depends["purge"] = true;
97                }
98            }
99        }
100
101
102    }
103
104    /**
105     * Add HTML meta to be able to debug
106     * @param Doku_Event $event
107     * @param $params
108     */
109    function addMeta(Doku_Event $event, $params)
110    {
111
112        $cacheManager = PluginUtility::getCacheManager();
113        $slots = $cacheManager->getCacheSlotResults();
114        foreach ($slots as $slotId => $modes) {
115
116            $cachedMode = [];
117            foreach ($modes as $mode => $values) {
118                if ($values[CacheManager::RESULT_STATUS] === true) {
119                    $metaContentData = $mode;
120                    if(!PluginUtility::isTest()){
121                        /**
122                         * @var DateTime $dateModified
123                         */
124                        $dateModified = $values[CacheManager::DATE_MODIFIED];
125                        $metaContentData .= ":". $dateModified->format('Y-m-d\TH:i:s');
126                    }
127                    $cachedMode[] = $metaContentData;
128                }
129            }
130
131            if (sizeof($cachedMode) === 0) {
132                $value = "nocache";
133            } else {
134                sort($cachedMode);
135                $value = implode(",", $cachedMode);
136            }
137
138            // Add cache information into the head meta
139            // to test
140            $event->data["meta"][] = array("name" => self::COMBO_CACHE_PREFIX . $slotId, "content" => hsc($value));
141        }
142
143    }
144
145    function close(Doku_Event $event, $params)
146    {
147        CacheManager::close();
148    }
149
150
151}
152