1<?php
2
3use ComboStrap\CacheExpirationDate;
4use ComboStrap\CacheManager;
5use ComboStrap\CacheMedia;
6use ComboStrap\CacheMenuItem;
7use ComboStrap\CacheReportHtmlDataBlockArray;
8use ComboStrap\Cron;
9use ComboStrap\ExceptionCombo;
10use ComboStrap\File;
11use ComboStrap\Http;
12use ComboStrap\Identity;
13use ComboStrap\Iso8601Date;
14use ComboStrap\LogUtility;
15use ComboStrap\MetadataDokuWikiStore;
16use ComboStrap\Page;
17use ComboStrap\PageDescription;
18use ComboStrap\PageH1;
19use ComboStrap\PageTitle;
20use ComboStrap\PluginUtility;
21use ComboStrap\ResourceName;
22use ComboStrap\Site;
23use dokuwiki\Cache\CacheRenderer;
24
25require_once(__DIR__ . '/../ComboStrap/PluginUtility.php');
26
27/**
28 * Can we use the parser cache
29 *
30 *
31 *
32 */
33class action_plugin_combo_cache extends DokuWiki_Action_Plugin
34{
35
36
37
38    const CANONICAL = "cache";
39    const STATIC_SCRIPT_NAMES = ["/lib/exe/jquery.php", "/lib/exe/js.php", "/lib/exe/css.php"];
40
41
42
43
44    /**
45     * @param Doku_Event_Handler $controller
46     */
47    function register(Doku_Event_Handler $controller)
48    {
49
50        /**
51         * Create a {@link \ComboStrap\CacheResult}
52         */
53        $controller->register_hook('PARSER_CACHE_USE', 'AFTER', $this, 'createCacheResult', array());
54
55
56        /**
57         * To add the cache result in the HTML
58         */
59        $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'addCacheLogHtmlDataBlock', array());
60
61
62        /**
63         * To delete the VARY on css.php, jquery.php, js.php
64         */
65        $controller->register_hook('INIT_LANG_LOAD', 'BEFORE', $this, 'deleteVaryFromStaticGeneratedResources', array());
66
67
68        /**
69         * Add a icon in the page tools menu
70         * https://www.dokuwiki.org/devel:event:menu_items_assembly
71         */
72        $controller->register_hook('MENU_ITEMS_ASSEMBLY', 'AFTER', $this, 'addMenuItem');
73
74    }
75
76    /**
77     *
78     * @param Doku_Event $event
79     * @param $params
80     */
81    function createCacheResult(Doku_Event $event, $params)
82    {
83
84        /**
85         * To log the cache used by bar
86         * @var \dokuwiki\Cache\CacheParser $data
87         */
88        $data = $event->data;
89        $slotId = $data->page;
90        $cacheReporter = CacheManager::getOrCreate()->getCacheResultsForSlot($slotId);
91        $cacheReporter->setData($event);
92
93
94    }
95
96
97    /**
98     * Add cache data to the rendered html page
99     * @param Doku_Event $event
100     * @param $params
101     */
102    function addCacheLogHtmlDataBlock(Doku_Event $event, $params)
103    {
104
105        if(!PluginUtility::isRenderingRequestedPageProcess()){
106            return;
107        }
108        $cacheSlotResults = CacheReportHtmlDataBlockArray::getFromRuntime();
109        $cacheJson = \ComboStrap\Json::createFromArray($cacheSlotResults);
110
111        if (PluginUtility::isDevOrTest()) {
112            $result = $cacheJson->toPrettyJsonString();
113        } else {
114            $result = $cacheJson->toMinifiedJsonString();
115        }
116
117        $event->data["script"][] = array(
118            "type" => CacheReportHtmlDataBlockArray::APPLICATION_COMBO_CACHE_JSON,
119            "_data" => $result,
120        );
121
122
123    }
124
125
126
127    /**
128     * Delete the Vary header
129     * @param Doku_Event $event
130     * @param $params
131     */
132    public static function deleteVaryFromStaticGeneratedResources(Doku_Event $event, $params)
133    {
134
135        $script = $_SERVER["SCRIPT_NAME"];
136        if (in_array($script, self::STATIC_SCRIPT_NAMES)) {
137            // To be extra sure, they must have the buster key
138            if (isset($_REQUEST[CacheMedia::CACHE_BUSTER_KEY])) {
139                self::deleteVaryHeader();
140            }
141        }
142
143    }
144
145    /**
146     *
147     * No Vary: Cookie
148     * Introduced at
149     * https://github.com/splitbrain/dokuwiki/issues/1594
150     * But cache problem at:
151     * https://github.com/splitbrain/dokuwiki/issues/2520
152     *
153     */
154    public static function deleteVaryHeader(): void
155    {
156        if (PluginUtility::getConfValue(action_plugin_combo_staticresource::CONF_STATIC_CACHE_ENABLED, 1)) {
157            Http::removeHeaderIfPresent("Vary");
158        }
159    }
160
161
162
163
164    function addMenuItem(Doku_Event $event, $param)
165    {
166
167        /**
168         * The `view` property defines the menu that is currently built
169         * https://www.dokuwiki.org/devel:menus
170         * If this is not the page menu, return
171         */
172        if ($event->data['view'] != 'page') return;
173
174        global $INFO;
175        if (!$INFO['exists']) {
176            return;
177        }
178        /**
179         * Cache is for manager
180         */
181        if (!Identity::isManager()) {
182            return;
183        }
184        array_splice($event->data['items'], -1, 0, array(new CacheMenuItem()));
185
186
187    }
188
189}
190