xref: /template/strap/action/cache.php (revision 70bbd7f1f72440223cc13f3495efdcb2b0a11514)
137748cd8SNickeau<?php
237748cd8SNickeau
337748cd8SNickeauuse ComboStrap\CacheManager;
44cadd4f8SNickeauuse ComboStrap\CacheMenuItem;
54cadd4f8SNickeauuse ComboStrap\CacheReportHtmlDataBlockArray;
604fd306cSNickeauuse ComboStrap\ExecutionContext;
71fa8c418SNickeauuse ComboStrap\Http;
84cadd4f8SNickeauuse ComboStrap\Identity;
904fd306cSNickeauuse ComboStrap\IFetcher;
1037748cd8SNickeauuse ComboStrap\PluginUtility;
1104fd306cSNickeauuse ComboStrap\SiteConfig;
1237748cd8SNickeau
1337748cd8SNickeaurequire_once(__DIR__ . '/../ComboStrap/PluginUtility.php');
1437748cd8SNickeau
1537748cd8SNickeau/**
1637748cd8SNickeau * Can we use the parser cache
174cadd4f8SNickeau *
184cadd4f8SNickeau *
194cadd4f8SNickeau *
2037748cd8SNickeau */
2137748cd8SNickeauclass action_plugin_combo_cache extends DokuWiki_Action_Plugin
2237748cd8SNickeau{
234cadd4f8SNickeau
2437748cd8SNickeau
251fa8c418SNickeau    const CANONICAL = "cache";
261fa8c418SNickeau    const STATIC_SCRIPT_NAMES = ["/lib/exe/jquery.php", "/lib/exe/js.php", "/lib/exe/css.php"];
271fa8c418SNickeau
28c3437056SNickeau
29c3437056SNickeau    /**
3037748cd8SNickeau     * @param Doku_Event_Handler $controller
3137748cd8SNickeau     */
3237748cd8SNickeau    function register(Doku_Event_Handler $controller)
3337748cd8SNickeau    {
3437748cd8SNickeau
3537748cd8SNickeau        /**
364cadd4f8SNickeau         * Create a {@link \ComboStrap\CacheResult}
3737748cd8SNickeau         */
384cadd4f8SNickeau        $controller->register_hook('PARSER_CACHE_USE', 'AFTER', $this, 'createCacheResult', array());
3937748cd8SNickeau
4037748cd8SNickeau
4137748cd8SNickeau        /**
42c3437056SNickeau         * To add the cache result in the HTML
431fa8c418SNickeau         */
44c3437056SNickeau        $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'addCacheLogHtmlDataBlock', array());
4537748cd8SNickeau
4637748cd8SNickeau
471fa8c418SNickeau        /**
481fa8c418SNickeau         * To delete the VARY on css.php, jquery.php, js.php
491fa8c418SNickeau         */
501fa8c418SNickeau        $controller->register_hook('INIT_LANG_LOAD', 'BEFORE', $this, 'deleteVaryFromStaticGeneratedResources', array());
511fa8c418SNickeau
524cadd4f8SNickeau
53c3437056SNickeau        /**
544cadd4f8SNickeau         * Add a icon in the page tools menu
554cadd4f8SNickeau         * https://www.dokuwiki.org/devel:event:menu_items_assembly
56c3437056SNickeau         */
574cadd4f8SNickeau        $controller->register_hook('MENU_ITEMS_ASSEMBLY', 'AFTER', $this, 'addMenuItem');
581fa8c418SNickeau
5937748cd8SNickeau    }
6037748cd8SNickeau
6137748cd8SNickeau    /**
6237748cd8SNickeau     *
6337748cd8SNickeau     * @param Doku_Event $event
6437748cd8SNickeau     * @param $params
6537748cd8SNickeau     */
664cadd4f8SNickeau    function createCacheResult(Doku_Event $event, $params)
6737748cd8SNickeau    {
6837748cd8SNickeau
6937748cd8SNickeau        /**
7037748cd8SNickeau         * To log the cache used by bar
7137748cd8SNickeau         * @var \dokuwiki\Cache\CacheParser $data
7237748cd8SNickeau         */
7337748cd8SNickeau        $data = $event->data;
74c3437056SNickeau        $slotId = $data->page;
7504fd306cSNickeau        if (empty($slotId)) {
7604fd306cSNickeau            // on edit mode, the page is emtpy
7704fd306cSNickeau            return;
7804fd306cSNickeau        }
7904fd306cSNickeau        $cacheReporter = CacheManager::getFromContextExecution()->getCacheResultsForSlot($slotId);
804cadd4f8SNickeau        $cacheReporter->setData($event);
8137748cd8SNickeau
8237748cd8SNickeau
8337748cd8SNickeau    }
8437748cd8SNickeau
8537748cd8SNickeau
8637748cd8SNickeau    /**
874cadd4f8SNickeau     * Add cache data to the rendered html page
8837748cd8SNickeau     * @param Doku_Event $event
8937748cd8SNickeau     * @param $params
9037748cd8SNickeau     */
91c3437056SNickeau    function addCacheLogHtmlDataBlock(Doku_Event $event, $params)
9237748cd8SNickeau    {
9337748cd8SNickeau
9404fd306cSNickeau        $isPublic = ExecutionContext::getActualOrCreateFromEnv()
9504fd306cSNickeau            ->isPublicationAction();
9604fd306cSNickeau        if (!$isPublic) {
974cadd4f8SNickeau            return;
984cadd4f8SNickeau        }
9904fd306cSNickeau        $cacheSlotResults = CacheReportHtmlDataBlockArray::getFromContext();
100c3437056SNickeau        $cacheJson = \ComboStrap\Json::createFromArray($cacheSlotResults);
10137748cd8SNickeau
102c3437056SNickeau        if (PluginUtility::isDevOrTest()) {
103c3437056SNickeau            $result = $cacheJson->toPrettyJsonString();
10437748cd8SNickeau        } else {
105c3437056SNickeau            $result = $cacheJson->toMinifiedJsonString();
10637748cd8SNickeau        }
10737748cd8SNickeau
108c3437056SNickeau        $event->data["script"][] = array(
1094cadd4f8SNickeau            "type" => CacheReportHtmlDataBlockArray::APPLICATION_COMBO_CACHE_JSON,
110c3437056SNickeau            "_data" => $result,
111c3437056SNickeau        );
11237748cd8SNickeau
1134cadd4f8SNickeau
11437748cd8SNickeau    }
11537748cd8SNickeau
1161fa8c418SNickeau
1171fa8c418SNickeau    /**
1181fa8c418SNickeau     * Delete the Vary header
1191fa8c418SNickeau     * @param Doku_Event $event
1201fa8c418SNickeau     * @param $params
1211fa8c418SNickeau     */
1221fa8c418SNickeau    public static function deleteVaryFromStaticGeneratedResources(Doku_Event $event, $params)
1231fa8c418SNickeau    {
1241fa8c418SNickeau
1251fa8c418SNickeau        $script = $_SERVER["SCRIPT_NAME"];
1261fa8c418SNickeau        if (in_array($script, self::STATIC_SCRIPT_NAMES)) {
127c3437056SNickeau            // To be extra sure, they must have the buster key
12804fd306cSNickeau            if (isset($_REQUEST[IFetcher::CACHE_BUSTER_KEY])) {
1291fa8c418SNickeau                self::deleteVaryHeader();
1301fa8c418SNickeau            }
1311fa8c418SNickeau        }
1321fa8c418SNickeau
1331fa8c418SNickeau    }
1341fa8c418SNickeau
1351fa8c418SNickeau    /**
1361fa8c418SNickeau     *
1371fa8c418SNickeau     * No Vary: Cookie
1381fa8c418SNickeau     * Introduced at
1391fa8c418SNickeau     * https://github.com/splitbrain/dokuwiki/issues/1594
1401fa8c418SNickeau     * But cache problem at:
1411fa8c418SNickeau     * https://github.com/splitbrain/dokuwiki/issues/2520
1421fa8c418SNickeau     *
1431fa8c418SNickeau     */
1441fa8c418SNickeau    public static function deleteVaryHeader(): void
1451fa8c418SNickeau    {
14604fd306cSNickeau        if (SiteConfig::getConfValue(action_plugin_combo_staticresource::CONF_STATIC_CACHE_ENABLED, 1)) {
1471fa8c418SNickeau            Http::removeHeaderIfPresent("Vary");
1481fa8c418SNickeau        }
1491fa8c418SNickeau    }
1501fa8c418SNickeau
1514cadd4f8SNickeau
1524cadd4f8SNickeau    function addMenuItem(Doku_Event $event, $param)
153c3437056SNickeau    {
154c3437056SNickeau
155c3437056SNickeau        /**
1564cadd4f8SNickeau         * The `view` property defines the menu that is currently built
1574cadd4f8SNickeau         * https://www.dokuwiki.org/devel:menus
1584cadd4f8SNickeau         * If this is not the page menu, return
159c3437056SNickeau         */
1604cadd4f8SNickeau        if ($event->data['view'] != 'page') return;
161c3437056SNickeau
1624cadd4f8SNickeau        global $INFO;
163*70bbd7f1Sgerardnico        $exists = $INFO['exists'] ?? null;
164*70bbd7f1Sgerardnico        if (!$exists) {
1654cadd4f8SNickeau            return;
166c3437056SNickeau        }
167c3437056SNickeau        /**
1684cadd4f8SNickeau         * Cache is for manager
169c3437056SNickeau         */
1704cadd4f8SNickeau        if (!Identity::isManager()) {
1714cadd4f8SNickeau            return;
172c3437056SNickeau        }
1734cadd4f8SNickeau        array_splice($event->data['items'], -1, 0, array(new CacheMenuItem()));
174c3437056SNickeau
175c3437056SNickeau
176c3437056SNickeau    }
17737748cd8SNickeau
17837748cd8SNickeau}
179