xref: /plugin/combo/action/snippets.php (revision 4cadd4f8c541149bdda95f080e38a6d4e3a640ca)
15f891b7eSNickeau<?php
25f891b7eSNickeau
3c3437056SNickeauuse ComboStrap\CacheManager;
4c3437056SNickeauuse ComboStrap\ExceptionCombo;
5*4cadd4f8SNickeauuse ComboStrap\HtmlDocument;
65f891b7eSNickeauuse ComboStrap\LogUtility;
7*4cadd4f8SNickeauuse ComboStrap\Page;
85f891b7eSNickeauuse ComboStrap\PluginUtility;
9*4cadd4f8SNickeauuse ComboStrap\RenderUtility;
10c3437056SNickeauuse ComboStrap\SnippetManager;
115f891b7eSNickeau
125f891b7eSNickeauif (!defined('DOKU_INC')) die();
135f891b7eSNickeau
145f891b7eSNickeau/**
155f891b7eSNickeau *
165f891b7eSNickeau *
175f891b7eSNickeau * Add the snippet needed by the components
185f891b7eSNickeau *
195f891b7eSNickeau */
205f891b7eSNickeauclass action_plugin_combo_snippets extends DokuWiki_Action_Plugin
215f891b7eSNickeau{
225f891b7eSNickeau
23*4cadd4f8SNickeau    const CLASS_SNIPPET_IN_CONTENT = "snippet-content-combo";
24*4cadd4f8SNickeau
255f891b7eSNickeau    /**
265f891b7eSNickeau     * @var bool - to trace if the header output was called
275f891b7eSNickeau     */
285f891b7eSNickeau    private $headerOutputWasCalled = false;
295f891b7eSNickeau
305f891b7eSNickeau    function __construct()
315f891b7eSNickeau    {
325f891b7eSNickeau        // enable direct access to language strings
335f891b7eSNickeau        // ie $this->lang
345f891b7eSNickeau        $this->setupLocale();
355f891b7eSNickeau    }
365f891b7eSNickeau
375f891b7eSNickeau    public function register(Doku_Event_Handler $controller)
385f891b7eSNickeau    {
398aa9d0e6Sgerardnico
4021913ab3SNickeau        /**
4121913ab3SNickeau         * To add the snippets in the header
4221913ab3SNickeau         */
435f891b7eSNickeau        $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'componentSnippetHead', array());
4421913ab3SNickeau
4521913ab3SNickeau        /**
4621913ab3SNickeau         * To add the snippets in the content
4721913ab3SNickeau         * if they have not been added to the header
48531e725cSNickeau         *
49531e725cSNickeau         * Not https://www.dokuwiki.org/devel:event:tpl_content_display TPL_ACT_RENDER
50531e725cSNickeau         * or https://www.dokuwiki.org/devel:event:tpl_act_render
51531e725cSNickeau         * because it works only for the main content
52531e725cSNickeau         * in {@link tpl_content()}
53531e725cSNickeau         *
54531e725cSNickeau         * We use
55531e725cSNickeau         * https://www.dokuwiki.org/devel:event:renderer_content_postprocess
56531e725cSNickeau         * that is in {@link p_render()} and takes into account also the slot page.
5721913ab3SNickeau         */
58531e725cSNickeau        $controller->register_hook('RENDERER_CONTENT_POSTPROCESS', 'AFTER', $this, 'componentSnippetContent', array());
598aa9d0e6Sgerardnico
6021913ab3SNickeau        /**
6121913ab3SNickeau         * To reset the value
6221913ab3SNickeau         */
6321913ab3SNickeau        $controller->register_hook('DOKUWIKI_DONE', 'BEFORE', $this, 'close', array());
648aa9d0e6Sgerardnico
6521913ab3SNickeau
665f891b7eSNickeau    }
675f891b7eSNickeau
685f891b7eSNickeau    /**
6932b85071SNickeau     * Reset variable
7032b85071SNickeau     * Otherwise in test, when we call it two times, it just fail
7132b85071SNickeau     */
7221913ab3SNickeau    function close()
7321913ab3SNickeau    {
7432b85071SNickeau
7532b85071SNickeau        $this->headerOutputWasCalled = false;
7632b85071SNickeau
7732b85071SNickeau        /**
7832b85071SNickeau         * Fighting the fact that in 7.2,
7932b85071SNickeau         * there is still a cache
8032b85071SNickeau         */
81*4cadd4f8SNickeau        SnippetManager::reset();
8232b85071SNickeau
8332b85071SNickeau    }
8432b85071SNickeau
8532b85071SNickeau    /**
865f891b7eSNickeau     * Dokuwiki has already a canonical methodology
875f891b7eSNickeau     * https://www.dokuwiki.org/canonical
885f891b7eSNickeau     *
895f891b7eSNickeau     * @param $event
905f891b7eSNickeau     */
915f891b7eSNickeau    function componentSnippetHead($event)
925f891b7eSNickeau    {
935f891b7eSNickeau
945f891b7eSNickeau
955f891b7eSNickeau        global $ID;
965f891b7eSNickeau        if (empty($ID)) {
97e8b2ff59SNickeau
9821913ab3SNickeau            global $_SERVER;
99e8b2ff59SNickeau            $scriptName = $_SERVER['SCRIPT_NAME'];
100e8b2ff59SNickeau
101e8b2ff59SNickeau            /**
102e8b2ff59SNickeau             * If this is an ajax call, return
103e8b2ff59SNickeau             * only if this not from webcode
104e8b2ff59SNickeau             */
105e8b2ff59SNickeau            if (strpos($scriptName, "/lib/exe/ajax.php") !== false) {
10621913ab3SNickeau                global $_REQUEST;
10721913ab3SNickeau                $call = $_REQUEST['call'];
10821913ab3SNickeau                if ($call != action_plugin_combo_webcode::CALL_ID) {
1095f891b7eSNickeau                    return;
1105f891b7eSNickeau                }
111e8b2ff59SNickeau            } else if (!(strpos($scriptName, "/lib/exe/detail.php") !== false)) {
112e8b2ff59SNickeau                /**
113e8b2ff59SNickeau                 * Image page has an header and footer that may needs snippet
114e8b2ff59SNickeau                 * We return only if this is not a image/detail page
115e8b2ff59SNickeau                 */
116e8b2ff59SNickeau                return;
11721913ab3SNickeau            }
11821913ab3SNickeau        }
1195f891b7eSNickeau
1205f891b7eSNickeau        /**
1215f891b7eSNickeau         * Advertise that the header output was called
1225f891b7eSNickeau         * If the user is using another template
1235f891b7eSNickeau         * than strap that does not put the component snippet
1245f891b7eSNickeau         * in the head
1255f891b7eSNickeau         * Used in
1265f891b7eSNickeau         */
1275f891b7eSNickeau        $this->headerOutputWasCalled = true;
1285f891b7eSNickeau
1295f891b7eSNickeau        $snippetManager = PluginUtility::getSnippetManager();
1305f891b7eSNickeau
1315f891b7eSNickeau        /**
132*4cadd4f8SNickeau         * For each processed slot in the page, retrieve the snippets
1335f891b7eSNickeau         */
134*4cadd4f8SNickeau        $cacheReporters = CacheManager::getOrCreate()->getCacheResults();
135*4cadd4f8SNickeau        if ($cacheReporters !== null) {
136*4cadd4f8SNickeau            foreach ($cacheReporters as $cacheReporter) {
1378aa9d0e6Sgerardnico
138*4cadd4f8SNickeau                foreach ($cacheReporter->getResults() as $report) {
1398aa9d0e6Sgerardnico
140*4cadd4f8SNickeau                    if ($report->getMode() !== HtmlDocument::mode) {
141*4cadd4f8SNickeau                        continue;
1425f891b7eSNickeau                    }
143*4cadd4f8SNickeau
144*4cadd4f8SNickeau                    $slotId = $report->getSlotId();
145*4cadd4f8SNickeau                    Page::createPageFromId($slotId)
146*4cadd4f8SNickeau                        ->getHtmlDocument()
147*4cadd4f8SNickeau                        ->loadSnippets();
148d2ffcff9Sgerardnico
1498aa9d0e6Sgerardnico                }
150c3437056SNickeau
1515f891b7eSNickeau
1528aa9d0e6Sgerardnico            }
153*4cadd4f8SNickeau        }
1545f891b7eSNickeau        /**
15521913ab3SNickeau         * Snippets
156*4cadd4f8SNickeau         * (Slot and request snippets)
1575f891b7eSNickeau         */
158*4cadd4f8SNickeau        try {
159*4cadd4f8SNickeau            $allSnippets = $snippetManager->getAllSnippetsToDokuwikiArray();
160*4cadd4f8SNickeau        } catch (ExceptionCombo $e) {
161*4cadd4f8SNickeau            LogUtility::msg("Error: We couldn't add the snippets in the head. Error: {$e->getMessage()}");
162*4cadd4f8SNickeau            return;
163*4cadd4f8SNickeau        }
164c3437056SNickeau        foreach ($allSnippets as $tagType => $tags) {
16521913ab3SNickeau
16621913ab3SNickeau            foreach ($tags as $tag) {
16721913ab3SNickeau                $event->data[$tagType][] = $tag;
1685f891b7eSNickeau            }
1695f891b7eSNickeau
1705f891b7eSNickeau        }
1715f891b7eSNickeau
1725f891b7eSNickeau        $snippetManager->close();
1735f891b7eSNickeau
1745f891b7eSNickeau    }
1755f891b7eSNickeau
1765f891b7eSNickeau    /**
1775f891b7eSNickeau     * Used if the template does not run the content
1785f891b7eSNickeau     * before the calling of the header as strap does.
1795f891b7eSNickeau     *
1805f891b7eSNickeau     * In this case, the {@link \ComboStrap\SnippetManager::close()} has
1815f891b7eSNickeau     * not run, and the snippets are still in memory.
1825f891b7eSNickeau     *
1835f891b7eSNickeau     * We store them in the HTML and they
1845f891b7eSNickeau     * follows then the HTML cache of DokuWiki
1855f891b7eSNickeau     * @param $event
1865f891b7eSNickeau     */
1875f891b7eSNickeau    function componentSnippetContent($event)
1885f891b7eSNickeau    {
1895f891b7eSNickeau
190531e725cSNickeau        $format = $event->data[0];
191531e725cSNickeau        if ($format !== "xhtml") {
192531e725cSNickeau            return;
193531e725cSNickeau        }
1945f891b7eSNickeau
1955f891b7eSNickeau        /**
196*4cadd4f8SNickeau         * Add snippet in the content
197*4cadd4f8SNickeau         *  - if the header output was already called
198*4cadd4f8SNickeau         *  - if this is not a page rendering (ie an admin rendering)
199*4cadd4f8SNickeau         * for instance, the upgrade plugin call {@link p_cached_output()} on local file
2005f891b7eSNickeau         */
201*4cadd4f8SNickeau        global $ACT;
202*4cadd4f8SNickeau        if ($ACT === RenderUtility::DYNAMIC_RENDERING) {
203*4cadd4f8SNickeau            return;
204*4cadd4f8SNickeau        }
205*4cadd4f8SNickeau        $putSnippetInContent =
206*4cadd4f8SNickeau            $this->headerOutputWasCalled
207*4cadd4f8SNickeau            ||
208*4cadd4f8SNickeau            ($ACT !== "show" && $ACT !== null); // admin page rendering
209*4cadd4f8SNickeau        if ($putSnippetInContent) {
2105f891b7eSNickeau
2115f891b7eSNickeau            $snippetManager = PluginUtility::getSnippetManager();
212531e725cSNickeau            $xhtmlContent = &$event->data[1];
213*4cadd4f8SNickeau            try {
214*4cadd4f8SNickeau                $snippets = $snippetManager->getAllSnippetsToDokuwikiArray();
215*4cadd4f8SNickeau            } catch (ExceptionCombo $e) {
216*4cadd4f8SNickeau                LogUtility::msg("Error: We couldn't add the snippets in the content. Error: {$e->getMessage()}");
217*4cadd4f8SNickeau                return;
218*4cadd4f8SNickeau            }
219*4cadd4f8SNickeau            if (sizeof($snippets) > 0) {
220*4cadd4f8SNickeau
221*4cadd4f8SNickeau                $class = self::CLASS_SNIPPET_IN_CONTENT;
222*4cadd4f8SNickeau                $xhtmlContent .= "<div class=\"$class\">\n";
223*4cadd4f8SNickeau                foreach ($snippets as $htmlElement => $tags) {
22421913ab3SNickeau
22521913ab3SNickeau                    foreach ($tags as $tag) {
226*4cadd4f8SNickeau                        $xhtmlContent .= DOKU_LF . "<$htmlElement";
22721913ab3SNickeau                        $attributes = "";
22821913ab3SNickeau                        $content = null;
229*4cadd4f8SNickeau
230*4cadd4f8SNickeau                        /**
231*4cadd4f8SNickeau                         * This code runs in editing mode
232*4cadd4f8SNickeau                         * or if the template is not strap
233*4cadd4f8SNickeau                         * No preload is then supported
234*4cadd4f8SNickeau                         */
235*4cadd4f8SNickeau                        if ($htmlElement === "link") {
236*4cadd4f8SNickeau                            $relValue = $tag["rel"];
237*4cadd4f8SNickeau                            $relAs = $tag["as"];
238*4cadd4f8SNickeau                            if ($relValue === "preload") {
239*4cadd4f8SNickeau                                if ($relAs === "style") {
240*4cadd4f8SNickeau                                    $tag["rel"] = "stylesheet";
241*4cadd4f8SNickeau                                    unset($tag["as"]);
242*4cadd4f8SNickeau                                }
243*4cadd4f8SNickeau                            }
244*4cadd4f8SNickeau                        }
245*4cadd4f8SNickeau
246*4cadd4f8SNickeau                        /**
247*4cadd4f8SNickeau                         * Print
248*4cadd4f8SNickeau                         */
24921913ab3SNickeau                        foreach ($tag as $attributeName => $attributeValue) {
250*4cadd4f8SNickeau                            if ($attributeName !== "_data") {
25121913ab3SNickeau                                $attributes .= " $attributeName=\"$attributeValue\"";
2525f891b7eSNickeau                            } else {
2535f891b7eSNickeau                                $content = $attributeValue;
2545f891b7eSNickeau                            }
2555f891b7eSNickeau                        }
256531e725cSNickeau                        $xhtmlContent .= "$attributes>";
2575f891b7eSNickeau                        if (!empty($content)) {
258531e725cSNickeau                            $xhtmlContent .= $content;
2595f891b7eSNickeau                        }
260*4cadd4f8SNickeau                        $xhtmlContent .= "</$htmlElement>" . DOKU_LF;
2615f891b7eSNickeau                    }
2625f891b7eSNickeau
2635f891b7eSNickeau                }
264*4cadd4f8SNickeau                $xhtmlContent .= "</div>\n";
265*4cadd4f8SNickeau
266*4cadd4f8SNickeau            }
2675f891b7eSNickeau
2685f891b7eSNickeau            $snippetManager->close();
2695f891b7eSNickeau
2705f891b7eSNickeau        }
2715f891b7eSNickeau
2725f891b7eSNickeau    }
2735f891b7eSNickeau
2748aa9d0e6Sgerardnico
2755f891b7eSNickeau}
276