xref: /plugin/combo/action/snippets.php (revision 32b85071e019dd3646a67c17fac4051338e495eb)
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
375f891b7eSNickeau        $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'componentSnippetHead', array());
38*32b85071SNickeau        $controller->register_hook('DOKUWIKI_DONE', 'BEFORE', $this, 'close', array());
395f891b7eSNickeau        $controller->register_hook('TPL_CONTENT_DISPLAY', 'BEFORE', $this, 'componentSnippetContent', array());
408aa9d0e6Sgerardnico
418aa9d0e6Sgerardnico
428aa9d0e6Sgerardnico        $controller->register_hook('PARSER_CACHE_USE', 'AFTER', $this, 'barParsed', array());
438aa9d0e6Sgerardnico
445f891b7eSNickeau    }
455f891b7eSNickeau
465f891b7eSNickeau    /**
47*32b85071SNickeau     * Reset variable
48*32b85071SNickeau     * Otherwise in test, when we call it two times, it just fail
49*32b85071SNickeau     */
50*32b85071SNickeau    function close(){
51*32b85071SNickeau
52*32b85071SNickeau        $this->headerOutputWasCalled = false;
53*32b85071SNickeau
54*32b85071SNickeau        /**
55*32b85071SNickeau         * Fighting the fact that in 7.2,
56*32b85071SNickeau         * there is still a cache
57*32b85071SNickeau         */
58*32b85071SNickeau        PluginUtility::initSnippetManager();
59*32b85071SNickeau
60*32b85071SNickeau    }
61*32b85071SNickeau
62*32b85071SNickeau    /**
635f891b7eSNickeau     * Dokuwiki has already a canonical methodology
645f891b7eSNickeau     * https://www.dokuwiki.org/canonical
655f891b7eSNickeau     *
665f891b7eSNickeau     * @param $event
675f891b7eSNickeau     */
685f891b7eSNickeau    function componentSnippetHead($event)
695f891b7eSNickeau    {
705f891b7eSNickeau
715f891b7eSNickeau
725f891b7eSNickeau        global $ID;
735f891b7eSNickeau        if (empty($ID)) {
745f891b7eSNickeau            return;
755f891b7eSNickeau        }
765f891b7eSNickeau
775f891b7eSNickeau        /**
785f891b7eSNickeau         * Advertise that the header output was called
795f891b7eSNickeau         * If the user is using another template
805f891b7eSNickeau         * than strap that does not put the component snippet
815f891b7eSNickeau         * in the head
825f891b7eSNickeau         * Used in
835f891b7eSNickeau         */
845f891b7eSNickeau        $this->headerOutputWasCalled = true;
855f891b7eSNickeau
865f891b7eSNickeau        $snippetManager = PluginUtility::getSnippetManager();
875f891b7eSNickeau
885f891b7eSNickeau        /**
898aa9d0e6Sgerardnico         * For each processed bar in the page
908aa9d0e6Sgerardnico         *   * retrieve the snippets from the cache or store the process one
918aa9d0e6Sgerardnico         *   * add the cache information in meta
925f891b7eSNickeau         */
938aa9d0e6Sgerardnico        $bars = $snippetManager->getBarsOfPage();
948aa9d0e6Sgerardnico        foreach ($bars as $bar => $servedFromCache) {
958aa9d0e6Sgerardnico
968aa9d0e6Sgerardnico            // Add cache meta for info
978aa9d0e6Sgerardnico            $event->data["meta"][] = array("name" => self::COMBO_CACHE_PREFIX . $bar, "content" => var_export($servedFromCache, true));
988aa9d0e6Sgerardnico
998aa9d0e6Sgerardnico            // Get or store the data
1008aa9d0e6Sgerardnico            $cache = new \dokuwiki\Cache\Cache($bar, "snippet");
1018aa9d0e6Sgerardnico
1028aa9d0e6Sgerardnico            // if the bar was served from the cache
1038aa9d0e6Sgerardnico            if ($servedFromCache) {
1048aa9d0e6Sgerardnico                // Retrieve snippets from previous run
1058aa9d0e6Sgerardnico
1065f891b7eSNickeau                $data = $cache->retrieveCache();
1078aa9d0e6Sgerardnico
1085f891b7eSNickeau                if (!empty($data)) {
1098aa9d0e6Sgerardnico                    $snippets = unserialize($data);
1108aa9d0e6Sgerardnico                    $snippetManager->addSnippetsFromCacheForBar($bar, $snippets);
1118aa9d0e6Sgerardnico
1128aa9d0e6Sgerardnico                    if (Site::debugIsOn()) {
1138aa9d0e6Sgerardnico                        LogUtility::log2file("Snippet cache file {$cache->cache} used", LogUtility::LVL_MSG_DEBUG);
1148aa9d0e6Sgerardnico                        $event->data['script'][] = array(
1158aa9d0e6Sgerardnico                            "type" => "application/json",
1168aa9d0e6Sgerardnico                            "_data" => json_encode($snippets),
1178aa9d0e6Sgerardnico                            "class" => "combo-snippet-cache-" . str_replace(":", "-", $bar));
1185f891b7eSNickeau                    }
119d2ffcff9Sgerardnico
1208aa9d0e6Sgerardnico                }
1218aa9d0e6Sgerardnico            } else {
1228aa9d0e6Sgerardnico                $snippets = $snippetManager->getSnippetsForBar($bar);
1238aa9d0e6Sgerardnico                if(!empty($snippets)) {
1248aa9d0e6Sgerardnico                    $cache->storeCache(serialize($snippets));
1258aa9d0e6Sgerardnico                }
1268aa9d0e6Sgerardnico            }
1275f891b7eSNickeau
1288aa9d0e6Sgerardnico        }
1295f891b7eSNickeau
1305f891b7eSNickeau        /**
1315f891b7eSNickeau         * tags
1325f891b7eSNickeau         */
1335f891b7eSNickeau        foreach ($snippetManager->getTags() as $component => $tags) {
1345f891b7eSNickeau            foreach ($tags as $tagType => $tagRows) {
1355f891b7eSNickeau                foreach ($tagRows as $tagRow) {
1365f891b7eSNickeau                    $tagRow["class"] = SnippetManager::getClassFromTag($component);;
1375f891b7eSNickeau                    $event->data[$tagType][] = $tagRow;
1385f891b7eSNickeau                }
1395f891b7eSNickeau            }
1405f891b7eSNickeau        }
1415f891b7eSNickeau
1425f891b7eSNickeau        /**
1435f891b7eSNickeau         * Css
1445f891b7eSNickeau         */
1455f891b7eSNickeau        foreach ($snippetManager->getCss() as $component => $snippet) {
1465f891b7eSNickeau            $event->data['style'][] = array(
1475f891b7eSNickeau                "class" => SnippetManager::getClassFromTag($component),
1485f891b7eSNickeau                "_data" => $snippet
1495f891b7eSNickeau            );
1505f891b7eSNickeau        }
1515f891b7eSNickeau
1525f891b7eSNickeau        /**
1535f891b7eSNickeau         * Javascript
1545f891b7eSNickeau         */
1555f891b7eSNickeau        foreach ($snippetManager->getJavascript() as $component => $snippet) {
1565f891b7eSNickeau            $event->data['script'][] = array(
1575f891b7eSNickeau                "class" => SnippetManager::getClassFromTag($component),
1585f891b7eSNickeau                "type" => "text/javascript",
1595f891b7eSNickeau                "_data" => $snippet
1605f891b7eSNickeau            );
1615f891b7eSNickeau        }
1625f891b7eSNickeau
1635f891b7eSNickeau
1645f891b7eSNickeau        $snippetManager->close();
1655f891b7eSNickeau
1665f891b7eSNickeau    }
1675f891b7eSNickeau
1685f891b7eSNickeau    /**
1695f891b7eSNickeau     * Used if the template does not run the content
1705f891b7eSNickeau     * before the calling of the header as strap does.
1715f891b7eSNickeau     *
1725f891b7eSNickeau     * In this case, the {@link \ComboStrap\SnippetManager::close()} has
1735f891b7eSNickeau     * not run, and the snippets are still in memory.
1745f891b7eSNickeau     *
1755f891b7eSNickeau     * We store them in the HTML and they
1765f891b7eSNickeau     * follows then the HTML cache of DokuWiki
1775f891b7eSNickeau     * @param $event
1785f891b7eSNickeau     */
1795f891b7eSNickeau    function componentSnippetContent($event)
1805f891b7eSNickeau    {
1815f891b7eSNickeau
1825f891b7eSNickeau
1835f891b7eSNickeau        /**
1845f891b7eSNickeau         * Run only if the header output was already called
1855f891b7eSNickeau         */
1865f891b7eSNickeau        if ($this->headerOutputWasCalled) {
1875f891b7eSNickeau
1885f891b7eSNickeau            $snippetManager = PluginUtility::getSnippetManager();
1895f891b7eSNickeau
1905f891b7eSNickeau            /**
1915f891b7eSNickeau             * tags
1925f891b7eSNickeau             */
1935f891b7eSNickeau            foreach ($snippetManager->getTags() as $component => $tags) {
1945f891b7eSNickeau                foreach ($tags as $tagType => $tagRows) {
1955f891b7eSNickeau                    foreach ($tagRows as $tagRow) {
1965f891b7eSNickeau                        $class = SnippetManager::getClassFromTag($component);
1975f891b7eSNickeau                        $event->data .= "<$tagType class=\"$class\"";
1985f891b7eSNickeau                        foreach ($tagRow as $attributeName => $attributeValue) {
1995f891b7eSNickeau                            if ($attributeName != "_data") {
2005f891b7eSNickeau                                $event->data .= " $attributeName=\"$attributeValue\"";
2015f891b7eSNickeau                            } else {
2025f891b7eSNickeau                                $content = $attributeValue;
2035f891b7eSNickeau                            }
2045f891b7eSNickeau                        }
2055f891b7eSNickeau                        $event->data .= ">";
2065f891b7eSNickeau                        if (!empty($content)) {
2075f891b7eSNickeau                            $event->data .= $content;
2085f891b7eSNickeau                        }
2095f891b7eSNickeau                        $event->data .= "</$tagType>";
2105f891b7eSNickeau                    }
2115f891b7eSNickeau                }
2125f891b7eSNickeau            }
2135f891b7eSNickeau
2145f891b7eSNickeau            /**
2155f891b7eSNickeau             * Css
2165f891b7eSNickeau             */
2175f891b7eSNickeau            foreach ($snippetManager->getCss() as $component => $snippet) {
2185f891b7eSNickeau
2195f891b7eSNickeau                $class = SnippetManager::getClassFromTag($component);
2205f891b7eSNickeau                $event->data .= "<style class=\"$class\">$snippet</style>" . DOKU_LF;
2215f891b7eSNickeau
2225f891b7eSNickeau            }
2235f891b7eSNickeau
2245f891b7eSNickeau            /**
2255f891b7eSNickeau             * Javascript
2265f891b7eSNickeau             */
2275f891b7eSNickeau            foreach ($snippetManager->getJavascript() as $component => $snippet) {
2285f891b7eSNickeau                $class = SnippetManager::getClassFromTag($component);
2295f891b7eSNickeau                $event->data .= "<script class=\"$class\" type=\"text/javascript\">$snippet</script>" . DOKU_LF;
2305f891b7eSNickeau            }
2315f891b7eSNickeau
2325f891b7eSNickeau            $snippetManager->close();
2335f891b7eSNickeau
2345f891b7eSNickeau            /**
2355f891b7eSNickeau             * Set the value back
2365f891b7eSNickeau             */
2375f891b7eSNickeau            $this->headerOutputWasCalled = false;
2385f891b7eSNickeau
2395f891b7eSNickeau        }
2405f891b7eSNickeau
2415f891b7eSNickeau    }
2425f891b7eSNickeau
2438aa9d0e6Sgerardnico
2445f891b7eSNickeau    /**
2458aa9d0e6Sgerardnico     *
2468aa9d0e6Sgerardnico     * @param $event
2475f891b7eSNickeau     */
2488aa9d0e6Sgerardnico    function barParsed($event)
2495f891b7eSNickeau    {
2508aa9d0e6Sgerardnico        $data = $event->data;
2518aa9d0e6Sgerardnico        if ($data->mode == "xhtml") {
2525f891b7eSNickeau
2538aa9d0e6Sgerardnico            /* @var CacheRenderer $data */
2548aa9d0e6Sgerardnico            $page = $data->page;
2558aa9d0e6Sgerardnico            $cached = $event->result;
2568aa9d0e6Sgerardnico            PluginUtility::getSnippetManager()->addBar($page, $cached);
2575f891b7eSNickeau
2585f891b7eSNickeau        }
2595f891b7eSNickeau
2608aa9d0e6Sgerardnico
2618aa9d0e6Sgerardnico    }
2625f891b7eSNickeau
2635f891b7eSNickeau
2645f891b7eSNickeau}
265