xref: /plugin/combo/action/snippets.php (revision 21913ab3235d516e2fa19c7e3929b555b3a2bda1)
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        /**
38         * To add the snippets in the header
39         */
40        $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'componentSnippetHead', array());
41
42        /**
43         * To add the snippets in the content
44         * if they have not been added to the header
45         */
46        $controller->register_hook('TPL_CONTENT_DISPLAY', 'BEFORE', $this, 'componentSnippetContent', array());
47
48        /**
49         * To reset the value
50         */
51        $controller->register_hook('DOKUWIKI_DONE', 'BEFORE', $this, 'close', array());
52
53
54        /**
55         * To log the cache used by bar
56         */
57        $controller->register_hook('PARSER_CACHE_USE', 'AFTER', $this, 'barParsed', array());
58
59    }
60
61    /**
62     * Reset variable
63     * Otherwise in test, when we call it two times, it just fail
64     */
65    function close()
66    {
67
68        $this->headerOutputWasCalled = false;
69
70        /**
71         * Fighting the fact that in 7.2,
72         * there is still a cache
73         */
74        PluginUtility::initSnippetManager();
75
76    }
77
78    /**
79     * Dokuwiki has already a canonical methodology
80     * https://www.dokuwiki.org/canonical
81     *
82     * @param $event
83     */
84    function componentSnippetHead($event)
85    {
86
87
88        global $ID;
89        if (empty($ID)) {
90            global $_SERVER;
91            $requestUri = $_SERVER['REQUEST_URI'];
92            if (!strpos($requestUri, "/lib/exe/ajax.php") !== false) {
93                global $_REQUEST;
94                $call = $_REQUEST['call'];
95                if($call != action_plugin_combo_webcode::CALL_ID) {
96                    return;
97                }
98            }
99        }
100
101        /**
102         * Advertise that the header output was called
103         * If the user is using another template
104         * than strap that does not put the component snippet
105         * in the head
106         * Used in
107         */
108        $this->headerOutputWasCalled = true;
109
110        $snippetManager = PluginUtility::getSnippetManager();
111
112        /**
113         * For each processed bar in the page
114         *   * retrieve the snippets from the cache or store the process one
115         *   * add the cache information in meta
116         */
117        $bars = $snippetManager->getBarsOfPage();
118        foreach ($bars as $bar => $servedFromCache) {
119
120            // Add cache information into the head meta
121            $event->data["meta"][] = array("name" => self::COMBO_CACHE_PREFIX . $bar, "content" => var_export($servedFromCache, true));
122
123            // Get or store the data
124            $cache = new \dokuwiki\Cache\Cache($bar, "snippet");
125
126            // if the bar was served from the cache
127            if ($servedFromCache) {
128
129                // Retrieve snippets from previous run
130                $data = $cache->retrieveCache();
131
132                if (!empty($data)) {
133                    $snippets = unserialize($data);
134                    $snippetManager->addSnippetsFromCacheForBar($bar, $snippets);
135
136                    if (Site::debugIsOn()) {
137                        LogUtility::log2file("Snippet cache file {$cache->cache} used", LogUtility::LVL_MSG_DEBUG);
138                        $event->data['script'][] = array(
139                            "type" => "application/json",
140                            "_data" => json_encode($snippets),
141                            "class" => "combo-snippet-cache-" . str_replace(":", "-", $bar));
142                    }
143
144                }
145            } else {
146                $snippets = $snippetManager->getSnippetsForBar($bar);
147                if (!empty($snippets)) {
148                    $cache->storeCache(serialize($snippets));
149                }
150            }
151
152        }
153
154        /**
155         * Snippets
156         */
157        foreach ($snippetManager->getSnippets() as $tagType => $tags) {
158
159            foreach ($tags as $tag) {
160                $event->data[$tagType][] = $tag;
161            }
162
163        }
164
165
166        $snippetManager->close();
167
168    }
169
170    /**
171     * Used if the template does not run the content
172     * before the calling of the header as strap does.
173     *
174     * In this case, the {@link \ComboStrap\SnippetManager::close()} has
175     * not run, and the snippets are still in memory.
176     *
177     * We store them in the HTML and they
178     * follows then the HTML cache of DokuWiki
179     * @param $event
180     */
181    function componentSnippetContent($event)
182    {
183
184
185        /**
186         * Run only if the header output was already called
187         */
188        if ($this->headerOutputWasCalled) {
189
190            $snippetManager = PluginUtility::getSnippetManager();
191
192            foreach ($snippetManager->getSnippets() as $tagType => $tags) {
193
194                foreach ($tags as $tag) {
195                    $event->data .= DOKU_LF . "<$tagType";
196                    $attributes = "";
197                    $content = null;
198                    foreach ($tag as $attributeName => $attributeValue) {
199                        if ($attributeName != "_data") {
200                            $attributes .= " $attributeName=\"$attributeValue\"";
201                        } else {
202                            $content = $attributeValue;
203                        }
204                    }
205                    $event->data .= "$attributes>";
206                    if (!empty($content)) {
207                        $event->data .= $content;
208                    }
209                    $event->data .= "</$tagType>" . DOKU_LF;
210                }
211
212            }
213
214            $snippetManager->close();
215
216            /**
217             * Set the value back
218             */
219            $this->headerOutputWasCalled = false;
220
221        }
222
223    }
224
225
226    /**
227     *
228     * @param $event
229     */
230    function barParsed($event)
231    {
232        $data = $event->data;
233        if ($data->mode == "xhtml") {
234
235            /* @var CacheRenderer $data */
236            $page = $data->page;
237            $cached = $event->result;
238            PluginUtility::getSnippetManager()->addBar($page, $cached);
239
240        }
241
242
243    }
244
245
246}
247