xref: /plugin/combo/action/snippets.php (revision 21913ab3235d516e2fa19c7e3929b555b3a2bda1)
15f891b7eSNickeau<?php
25f891b7eSNickeau
35f891b7eSNickeauuse ComboStrap\LogUtility;
45f891b7eSNickeauuse ComboStrap\PluginUtility;
58aa9d0e6Sgerardnicouse ComboStrap\Site;
65f891b7eSNickeauuse ComboStrap\SnippetManager;
78aa9d0e6Sgerardnicouse dokuwiki\Cache\CacheRenderer;
85f891b7eSNickeau
95f891b7eSNickeauif (!defined('DOKU_INC')) die();
105f891b7eSNickeau
115f891b7eSNickeau/**
125f891b7eSNickeau *
135f891b7eSNickeau *
145f891b7eSNickeau * Add the snippet needed by the components
155f891b7eSNickeau *
165f891b7eSNickeau */
175f891b7eSNickeauclass action_plugin_combo_snippets extends DokuWiki_Action_Plugin
185f891b7eSNickeau{
195f891b7eSNickeau
208aa9d0e6Sgerardnico    const COMBO_CACHE_PREFIX = "combo:cache:";
215f891b7eSNickeau
225f891b7eSNickeau    /**
235f891b7eSNickeau     * @var bool - to trace if the header output was called
245f891b7eSNickeau     */
255f891b7eSNickeau    private $headerOutputWasCalled = false;
265f891b7eSNickeau
275f891b7eSNickeau    function __construct()
285f891b7eSNickeau    {
295f891b7eSNickeau        // enable direct access to language strings
305f891b7eSNickeau        // ie $this->lang
315f891b7eSNickeau        $this->setupLocale();
325f891b7eSNickeau    }
335f891b7eSNickeau
345f891b7eSNickeau    public function register(Doku_Event_Handler $controller)
355f891b7eSNickeau    {
368aa9d0e6Sgerardnico
37*21913ab3SNickeau        /**
38*21913ab3SNickeau         * To add the snippets in the header
39*21913ab3SNickeau         */
405f891b7eSNickeau        $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'componentSnippetHead', array());
41*21913ab3SNickeau
42*21913ab3SNickeau        /**
43*21913ab3SNickeau         * To add the snippets in the content
44*21913ab3SNickeau         * if they have not been added to the header
45*21913ab3SNickeau         */
465f891b7eSNickeau        $controller->register_hook('TPL_CONTENT_DISPLAY', 'BEFORE', $this, 'componentSnippetContent', array());
478aa9d0e6Sgerardnico
48*21913ab3SNickeau        /**
49*21913ab3SNickeau         * To reset the value
50*21913ab3SNickeau         */
51*21913ab3SNickeau        $controller->register_hook('DOKUWIKI_DONE', 'BEFORE', $this, 'close', array());
528aa9d0e6Sgerardnico
53*21913ab3SNickeau
54*21913ab3SNickeau        /**
55*21913ab3SNickeau         * To log the cache used by bar
56*21913ab3SNickeau         */
578aa9d0e6Sgerardnico        $controller->register_hook('PARSER_CACHE_USE', 'AFTER', $this, 'barParsed', array());
588aa9d0e6Sgerardnico
595f891b7eSNickeau    }
605f891b7eSNickeau
615f891b7eSNickeau    /**
6232b85071SNickeau     * Reset variable
6332b85071SNickeau     * Otherwise in test, when we call it two times, it just fail
6432b85071SNickeau     */
65*21913ab3SNickeau    function close()
66*21913ab3SNickeau    {
6732b85071SNickeau
6832b85071SNickeau        $this->headerOutputWasCalled = false;
6932b85071SNickeau
7032b85071SNickeau        /**
7132b85071SNickeau         * Fighting the fact that in 7.2,
7232b85071SNickeau         * there is still a cache
7332b85071SNickeau         */
7432b85071SNickeau        PluginUtility::initSnippetManager();
7532b85071SNickeau
7632b85071SNickeau    }
7732b85071SNickeau
7832b85071SNickeau    /**
795f891b7eSNickeau     * Dokuwiki has already a canonical methodology
805f891b7eSNickeau     * https://www.dokuwiki.org/canonical
815f891b7eSNickeau     *
825f891b7eSNickeau     * @param $event
835f891b7eSNickeau     */
845f891b7eSNickeau    function componentSnippetHead($event)
855f891b7eSNickeau    {
865f891b7eSNickeau
875f891b7eSNickeau
885f891b7eSNickeau        global $ID;
895f891b7eSNickeau        if (empty($ID)) {
90*21913ab3SNickeau            global $_SERVER;
91*21913ab3SNickeau            $requestUri = $_SERVER['REQUEST_URI'];
92*21913ab3SNickeau            if (!strpos($requestUri, "/lib/exe/ajax.php") !== false) {
93*21913ab3SNickeau                global $_REQUEST;
94*21913ab3SNickeau                $call = $_REQUEST['call'];
95*21913ab3SNickeau                if($call != action_plugin_combo_webcode::CALL_ID) {
965f891b7eSNickeau                    return;
975f891b7eSNickeau                }
98*21913ab3SNickeau            }
99*21913ab3SNickeau        }
1005f891b7eSNickeau
1015f891b7eSNickeau        /**
1025f891b7eSNickeau         * Advertise that the header output was called
1035f891b7eSNickeau         * If the user is using another template
1045f891b7eSNickeau         * than strap that does not put the component snippet
1055f891b7eSNickeau         * in the head
1065f891b7eSNickeau         * Used in
1075f891b7eSNickeau         */
1085f891b7eSNickeau        $this->headerOutputWasCalled = true;
1095f891b7eSNickeau
1105f891b7eSNickeau        $snippetManager = PluginUtility::getSnippetManager();
1115f891b7eSNickeau
1125f891b7eSNickeau        /**
1138aa9d0e6Sgerardnico         * For each processed bar in the page
1148aa9d0e6Sgerardnico         *   * retrieve the snippets from the cache or store the process one
1158aa9d0e6Sgerardnico         *   * add the cache information in meta
1165f891b7eSNickeau         */
1178aa9d0e6Sgerardnico        $bars = $snippetManager->getBarsOfPage();
1188aa9d0e6Sgerardnico        foreach ($bars as $bar => $servedFromCache) {
1198aa9d0e6Sgerardnico
120*21913ab3SNickeau            // Add cache information into the head meta
1218aa9d0e6Sgerardnico            $event->data["meta"][] = array("name" => self::COMBO_CACHE_PREFIX . $bar, "content" => var_export($servedFromCache, true));
1228aa9d0e6Sgerardnico
1238aa9d0e6Sgerardnico            // Get or store the data
1248aa9d0e6Sgerardnico            $cache = new \dokuwiki\Cache\Cache($bar, "snippet");
1258aa9d0e6Sgerardnico
1268aa9d0e6Sgerardnico            // if the bar was served from the cache
1278aa9d0e6Sgerardnico            if ($servedFromCache) {
1288aa9d0e6Sgerardnico
129*21913ab3SNickeau                // Retrieve snippets from previous run
1305f891b7eSNickeau                $data = $cache->retrieveCache();
1318aa9d0e6Sgerardnico
1325f891b7eSNickeau                if (!empty($data)) {
1338aa9d0e6Sgerardnico                    $snippets = unserialize($data);
1348aa9d0e6Sgerardnico                    $snippetManager->addSnippetsFromCacheForBar($bar, $snippets);
1358aa9d0e6Sgerardnico
1368aa9d0e6Sgerardnico                    if (Site::debugIsOn()) {
1378aa9d0e6Sgerardnico                        LogUtility::log2file("Snippet cache file {$cache->cache} used", LogUtility::LVL_MSG_DEBUG);
1388aa9d0e6Sgerardnico                        $event->data['script'][] = array(
1398aa9d0e6Sgerardnico                            "type" => "application/json",
1408aa9d0e6Sgerardnico                            "_data" => json_encode($snippets),
1418aa9d0e6Sgerardnico                            "class" => "combo-snippet-cache-" . str_replace(":", "-", $bar));
1425f891b7eSNickeau                    }
143d2ffcff9Sgerardnico
1448aa9d0e6Sgerardnico                }
1458aa9d0e6Sgerardnico            } else {
1468aa9d0e6Sgerardnico                $snippets = $snippetManager->getSnippetsForBar($bar);
1478aa9d0e6Sgerardnico                if (!empty($snippets)) {
1488aa9d0e6Sgerardnico                    $cache->storeCache(serialize($snippets));
1498aa9d0e6Sgerardnico                }
1508aa9d0e6Sgerardnico            }
1515f891b7eSNickeau
1528aa9d0e6Sgerardnico        }
1535f891b7eSNickeau
1545f891b7eSNickeau        /**
155*21913ab3SNickeau         * Snippets
1565f891b7eSNickeau         */
157*21913ab3SNickeau        foreach ($snippetManager->getSnippets() as $tagType => $tags) {
158*21913ab3SNickeau
159*21913ab3SNickeau            foreach ($tags as $tag) {
160*21913ab3SNickeau                $event->data[$tagType][] = $tag;
1615f891b7eSNickeau            }
1625f891b7eSNickeau
1635f891b7eSNickeau        }
1645f891b7eSNickeau
1655f891b7eSNickeau
1665f891b7eSNickeau        $snippetManager->close();
1675f891b7eSNickeau
1685f891b7eSNickeau    }
1695f891b7eSNickeau
1705f891b7eSNickeau    /**
1715f891b7eSNickeau     * Used if the template does not run the content
1725f891b7eSNickeau     * before the calling of the header as strap does.
1735f891b7eSNickeau     *
1745f891b7eSNickeau     * In this case, the {@link \ComboStrap\SnippetManager::close()} has
1755f891b7eSNickeau     * not run, and the snippets are still in memory.
1765f891b7eSNickeau     *
1775f891b7eSNickeau     * We store them in the HTML and they
1785f891b7eSNickeau     * follows then the HTML cache of DokuWiki
1795f891b7eSNickeau     * @param $event
1805f891b7eSNickeau     */
1815f891b7eSNickeau    function componentSnippetContent($event)
1825f891b7eSNickeau    {
1835f891b7eSNickeau
1845f891b7eSNickeau
1855f891b7eSNickeau        /**
1865f891b7eSNickeau         * Run only if the header output was already called
1875f891b7eSNickeau         */
1885f891b7eSNickeau        if ($this->headerOutputWasCalled) {
1895f891b7eSNickeau
1905f891b7eSNickeau            $snippetManager = PluginUtility::getSnippetManager();
1915f891b7eSNickeau
192*21913ab3SNickeau            foreach ($snippetManager->getSnippets() as $tagType => $tags) {
193*21913ab3SNickeau
194*21913ab3SNickeau                foreach ($tags as $tag) {
195*21913ab3SNickeau                    $event->data .= DOKU_LF . "<$tagType";
196*21913ab3SNickeau                    $attributes = "";
197*21913ab3SNickeau                    $content = null;
198*21913ab3SNickeau                    foreach ($tag as $attributeName => $attributeValue) {
1995f891b7eSNickeau                        if ($attributeName != "_data") {
200*21913ab3SNickeau                            $attributes .= " $attributeName=\"$attributeValue\"";
2015f891b7eSNickeau                        } else {
2025f891b7eSNickeau                            $content = $attributeValue;
2035f891b7eSNickeau                        }
2045f891b7eSNickeau                    }
205*21913ab3SNickeau                    $event->data .= "$attributes>";
2065f891b7eSNickeau                    if (!empty($content)) {
2075f891b7eSNickeau                        $event->data .= $content;
2085f891b7eSNickeau                    }
209*21913ab3SNickeau                    $event->data .= "</$tagType>" . DOKU_LF;
2105f891b7eSNickeau                }
2115f891b7eSNickeau
2125f891b7eSNickeau            }
2135f891b7eSNickeau
2145f891b7eSNickeau            $snippetManager->close();
2155f891b7eSNickeau
2165f891b7eSNickeau            /**
2175f891b7eSNickeau             * Set the value back
2185f891b7eSNickeau             */
2195f891b7eSNickeau            $this->headerOutputWasCalled = false;
2205f891b7eSNickeau
2215f891b7eSNickeau        }
2225f891b7eSNickeau
2235f891b7eSNickeau    }
2245f891b7eSNickeau
2258aa9d0e6Sgerardnico
2265f891b7eSNickeau    /**
2278aa9d0e6Sgerardnico     *
2288aa9d0e6Sgerardnico     * @param $event
2295f891b7eSNickeau     */
2308aa9d0e6Sgerardnico    function barParsed($event)
2315f891b7eSNickeau    {
2328aa9d0e6Sgerardnico        $data = $event->data;
2338aa9d0e6Sgerardnico        if ($data->mode == "xhtml") {
2345f891b7eSNickeau
2358aa9d0e6Sgerardnico            /* @var CacheRenderer $data */
2368aa9d0e6Sgerardnico            $page = $data->page;
2378aa9d0e6Sgerardnico            $cached = $event->result;
2388aa9d0e6Sgerardnico            PluginUtility::getSnippetManager()->addBar($page, $cached);
2395f891b7eSNickeau
2405f891b7eSNickeau        }
2415f891b7eSNickeau
2428aa9d0e6Sgerardnico
2438aa9d0e6Sgerardnico    }
2445f891b7eSNickeau
2455f891b7eSNickeau
2465f891b7eSNickeau}
247