xref: /plugin/combo/action/snippets.php (revision 5f891b7e09648e05e78f5882f3fdde1e9df9b0f1)
1*5f891b7eSNickeau<?php
2*5f891b7eSNickeau
3*5f891b7eSNickeauuse ComboStrap\LogUtility;
4*5f891b7eSNickeauuse ComboStrap\MetadataUtility;
5*5f891b7eSNickeauuse ComboStrap\PluginUtility;
6*5f891b7eSNickeauuse ComboStrap\Page;
7*5f891b7eSNickeauuse ComboStrap\SnippetManager;
8*5f891b7eSNickeauuse ComboStrap\TplUtility;
9*5f891b7eSNickeauuse dokuwiki\Cache\CacheRenderer;
10*5f891b7eSNickeau
11*5f891b7eSNickeauif (!defined('DOKU_INC')) die();
12*5f891b7eSNickeau
13*5f891b7eSNickeau/**
14*5f891b7eSNickeau *
15*5f891b7eSNickeau *
16*5f891b7eSNickeau * Add the snippet needed by the components
17*5f891b7eSNickeau *
18*5f891b7eSNickeau */
19*5f891b7eSNickeauclass action_plugin_combo_snippets extends DokuWiki_Action_Plugin
20*5f891b7eSNickeau{
21*5f891b7eSNickeau
22*5f891b7eSNickeau
23*5f891b7eSNickeau    /**
24*5f891b7eSNickeau     * @var bool - to trace if the header output was called
25*5f891b7eSNickeau     */
26*5f891b7eSNickeau    private $headerOutputWasCalled = false;
27*5f891b7eSNickeau
28*5f891b7eSNickeau    function __construct()
29*5f891b7eSNickeau    {
30*5f891b7eSNickeau        // enable direct access to language strings
31*5f891b7eSNickeau        // ie $this->lang
32*5f891b7eSNickeau        $this->setupLocale();
33*5f891b7eSNickeau    }
34*5f891b7eSNickeau
35*5f891b7eSNickeau    public function register(Doku_Event_Handler $controller)
36*5f891b7eSNickeau    {
37*5f891b7eSNickeau        $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'componentSnippetHead', array());
38*5f891b7eSNickeau        $controller->register_hook('TPL_CONTENT_DISPLAY', 'BEFORE', $this, 'componentSnippetContent', array());
39*5f891b7eSNickeau    }
40*5f891b7eSNickeau
41*5f891b7eSNickeau    /**
42*5f891b7eSNickeau     * Dokuwiki has already a canonical methodology
43*5f891b7eSNickeau     * https://www.dokuwiki.org/canonical
44*5f891b7eSNickeau     *
45*5f891b7eSNickeau     * @param $event
46*5f891b7eSNickeau     */
47*5f891b7eSNickeau    function componentSnippetHead($event)
48*5f891b7eSNickeau    {
49*5f891b7eSNickeau
50*5f891b7eSNickeau
51*5f891b7eSNickeau        global $ID;
52*5f891b7eSNickeau        if (empty($ID)) {
53*5f891b7eSNickeau            return;
54*5f891b7eSNickeau        }
55*5f891b7eSNickeau
56*5f891b7eSNickeau        /**
57*5f891b7eSNickeau         * Advertise that the header output was called
58*5f891b7eSNickeau         * If the user is using another template
59*5f891b7eSNickeau         * than strap that does not put the component snippet
60*5f891b7eSNickeau         * in the head
61*5f891b7eSNickeau         * Used in
62*5f891b7eSNickeau         */
63*5f891b7eSNickeau        $this->headerOutputWasCalled = true;
64*5f891b7eSNickeau
65*5f891b7eSNickeau        $snippetManager = PluginUtility::getSnippetManager();
66*5f891b7eSNickeau
67*5f891b7eSNickeau        /**
68*5f891b7eSNickeau         * Because the cache is at the bar level,
69*5f891b7eSNickeau         * a rendering for a page may run without the others
70*5f891b7eSNickeau         * Therefore we saved the data in between
71*5f891b7eSNickeau         * (The storage is done at the page level)
72*5f891b7eSNickeau         * Adapted from {@link p_cached_output()}
73*5f891b7eSNickeau         */
74*5f891b7eSNickeau        $storedArray = array();
75*5f891b7eSNickeau        $file = wikiFN($ID);
76*5f891b7eSNickeau        $cache = new CacheRenderer($ID, $file, "snippet");
77*5f891b7eSNickeau        if ($cache->useCache()) { // useCache means isCacheUsable
78*5f891b7eSNickeau            $data = $cache->retrieveCache();
79*5f891b7eSNickeau            global $conf;
80*5f891b7eSNickeau            if ($conf['allowdebug']) {
81*5f891b7eSNickeau                LogUtility::log2file("Snippet cache file {$cache->cache} used");
82*5f891b7eSNickeau            }
83*5f891b7eSNickeau            if (!empty($data)) {
84*5f891b7eSNickeau                $storedArray = unserialize($data);
85*5f891b7eSNickeau            }
86*5f891b7eSNickeau            $snippetManager->mergeWithPreviousRun($storedArray);
87*5f891b7eSNickeau        }
88*5f891b7eSNickeau        $cache->storeCache(serialize($snippetManager->getData()));
89*5f891b7eSNickeau
90*5f891b7eSNickeau
91*5f891b7eSNickeau        /**
92*5f891b7eSNickeau         * tags
93*5f891b7eSNickeau         */
94*5f891b7eSNickeau        foreach ($snippetManager->getTags() as $component => $tags) {
95*5f891b7eSNickeau            foreach ($tags as $tagType => $tagRows) {
96*5f891b7eSNickeau                foreach ($tagRows as $tagRow) {
97*5f891b7eSNickeau                    $tagRow["class"] = SnippetManager::getClassFromTag($component);;
98*5f891b7eSNickeau                    $event->data[$tagType][] = $tagRow;
99*5f891b7eSNickeau                }
100*5f891b7eSNickeau            }
101*5f891b7eSNickeau        }
102*5f891b7eSNickeau
103*5f891b7eSNickeau        /**
104*5f891b7eSNickeau         * Css
105*5f891b7eSNickeau         */
106*5f891b7eSNickeau        foreach ($snippetManager->getCss() as $component => $snippet) {
107*5f891b7eSNickeau            $event->data['style'][] = array(
108*5f891b7eSNickeau                "class" => SnippetManager::getClassFromTag($component),
109*5f891b7eSNickeau                "_data" => $snippet
110*5f891b7eSNickeau            );
111*5f891b7eSNickeau        }
112*5f891b7eSNickeau
113*5f891b7eSNickeau        /**
114*5f891b7eSNickeau         * Javascript
115*5f891b7eSNickeau         */
116*5f891b7eSNickeau        foreach ($snippetManager->getJavascript() as $component => $snippet) {
117*5f891b7eSNickeau            $event->data['script'][] = array(
118*5f891b7eSNickeau                "class" => SnippetManager::getClassFromTag($component),
119*5f891b7eSNickeau                "type" => "text/javascript",
120*5f891b7eSNickeau                "_data" => $snippet
121*5f891b7eSNickeau            );
122*5f891b7eSNickeau        }
123*5f891b7eSNickeau
124*5f891b7eSNickeau
125*5f891b7eSNickeau        $snippetManager->close();
126*5f891b7eSNickeau
127*5f891b7eSNickeau    }
128*5f891b7eSNickeau
129*5f891b7eSNickeau    /**
130*5f891b7eSNickeau     * Used if the template does not run the content
131*5f891b7eSNickeau     * before the calling of the header as strap does.
132*5f891b7eSNickeau     *
133*5f891b7eSNickeau     * In this case, the {@link \ComboStrap\SnippetManager::close()} has
134*5f891b7eSNickeau     * not run, and the snippets are still in memory.
135*5f891b7eSNickeau     *
136*5f891b7eSNickeau     * We store them in the HTML and they
137*5f891b7eSNickeau     * follows then the HTML cache of DokuWiki
138*5f891b7eSNickeau     * @param $event
139*5f891b7eSNickeau     */
140*5f891b7eSNickeau    function componentSnippetContent($event)
141*5f891b7eSNickeau    {
142*5f891b7eSNickeau
143*5f891b7eSNickeau
144*5f891b7eSNickeau        /**
145*5f891b7eSNickeau         * Run only if the header output was already called
146*5f891b7eSNickeau         */
147*5f891b7eSNickeau        if ($this->headerOutputWasCalled) {
148*5f891b7eSNickeau
149*5f891b7eSNickeau            $snippetManager = PluginUtility::getSnippetManager();
150*5f891b7eSNickeau
151*5f891b7eSNickeau            /**
152*5f891b7eSNickeau             * tags
153*5f891b7eSNickeau             */
154*5f891b7eSNickeau            foreach ($snippetManager->getTags() as $component => $tags) {
155*5f891b7eSNickeau                foreach ($tags as $tagType => $tagRows) {
156*5f891b7eSNickeau                    foreach ($tagRows as $tagRow) {
157*5f891b7eSNickeau                        $class = SnippetManager::getClassFromTag($component);
158*5f891b7eSNickeau                        $event->data .= "<$tagType class=\"$class\"";
159*5f891b7eSNickeau                        foreach ($tagRow as $attributeName => $attributeValue) {
160*5f891b7eSNickeau                            if ($attributeName != "_data") {
161*5f891b7eSNickeau                                $event->data .= " $attributeName=\"$attributeValue\"";
162*5f891b7eSNickeau                            } else {
163*5f891b7eSNickeau                                $content = $attributeValue;
164*5f891b7eSNickeau                            }
165*5f891b7eSNickeau                        }
166*5f891b7eSNickeau                        $event->data .= ">";
167*5f891b7eSNickeau                        if (!empty($content)) {
168*5f891b7eSNickeau                            $event->data .= $content;
169*5f891b7eSNickeau                        }
170*5f891b7eSNickeau                        $event->data .= "</$tagType>";
171*5f891b7eSNickeau                    }
172*5f891b7eSNickeau                }
173*5f891b7eSNickeau            }
174*5f891b7eSNickeau
175*5f891b7eSNickeau            /**
176*5f891b7eSNickeau             * Css
177*5f891b7eSNickeau             */
178*5f891b7eSNickeau            foreach ($snippetManager->getCss() as $component => $snippet) {
179*5f891b7eSNickeau
180*5f891b7eSNickeau                $class = SnippetManager::getClassFromTag($component);
181*5f891b7eSNickeau                $event->data .= "<style class=\"$class\">$snippet</style>" . DOKU_LF;
182*5f891b7eSNickeau
183*5f891b7eSNickeau            }
184*5f891b7eSNickeau
185*5f891b7eSNickeau            /**
186*5f891b7eSNickeau             * Javascript
187*5f891b7eSNickeau             */
188*5f891b7eSNickeau            foreach ($snippetManager->getJavascript() as $component => $snippet) {
189*5f891b7eSNickeau                $class = SnippetManager::getClassFromTag($component);
190*5f891b7eSNickeau                $event->data .= "<script class=\"$class\" type=\"text/javascript\">$snippet</script>" . DOKU_LF;
191*5f891b7eSNickeau            }
192*5f891b7eSNickeau
193*5f891b7eSNickeau            $snippetManager->close();
194*5f891b7eSNickeau
195*5f891b7eSNickeau            /**
196*5f891b7eSNickeau             * Set the value back
197*5f891b7eSNickeau             */
198*5f891b7eSNickeau            $this->headerOutputWasCalled = false;
199*5f891b7eSNickeau
200*5f891b7eSNickeau        }
201*5f891b7eSNickeau
202*5f891b7eSNickeau    }
203*5f891b7eSNickeau
204*5f891b7eSNickeau    /**
205*5f891b7eSNickeau     * Adapted from {@link p_cached_output()}
206*5f891b7eSNickeau     */
207*5f891b7eSNickeau    function getCachedSnippet()
208*5f891b7eSNickeau    {
209*5f891b7eSNickeau
210*5f891b7eSNickeau        global $ID;
211*5f891b7eSNickeau        $file = wikiFN($ID);
212*5f891b7eSNickeau        $format = "combo_head";
213*5f891b7eSNickeau        global $conf;
214*5f891b7eSNickeau
215*5f891b7eSNickeau
216*5f891b7eSNickeau    }
217*5f891b7eSNickeau
218*5f891b7eSNickeau//    function storeSnippetArray()
219*5f891b7eSNickeau//    {
220*5f891b7eSNickeau//        global $conf;
221*5f891b7eSNickeau//
222*5f891b7eSNickeau//        $cache = new CacheRenderer($ID, $file, $format);
223*5f891b7eSNickeau//        if (!empty($headHtml)) {
224*5f891b7eSNickeau//            if ($cache->storeCache($headHtml)) {              // storeCache() attempts to save cachefile
225*5f891b7eSNickeau//                if ($conf['allowdebug']) {
226*5f891b7eSNickeau//
227*5f891b7eSNickeau//                    LogUtility::log2file("No cache file used, but created {$cache->cache} ");
228*5f891b7eSNickeau//                }
229*5f891b7eSNickeau//            } else {
230*5f891b7eSNickeau//                $cache->removeCache();                     //try to delete cachefile
231*5f891b7eSNickeau//                if ($conf['allowdebug']) {
232*5f891b7eSNickeau//                    LogUtility::log2file("no cachefile used, caching forbidden");
233*5f891b7eSNickeau//                }
234*5f891b7eSNickeau//            }
235*5f891b7eSNickeau//        }
236*5f891b7eSNickeau//    }
237*5f891b7eSNickeau
238*5f891b7eSNickeau
239*5f891b7eSNickeau}
240