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