xref: /plugin/combo/action/webcode.php (revision 28451e1e279162c69b8183f0c5671439573c3ef2)
121913ab3SNickeau<?php
221913ab3SNickeau
34cadd4f8SNickeauuse ComboStrap\ExceptionCombo;
4*28451e1eSgerardnicouse ComboStrap\Identity;
521913ab3SNickeauuse ComboStrap\PluginUtility;
621913ab3SNickeauuse ComboStrap\Site;
721913ab3SNickeauuse ComboStrap\TplUtility;
821913ab3SNickeau
921913ab3SNickeauif (!defined('DOKU_INC')) die();
1021913ab3SNickeau
1121913ab3SNickeau/**
1221913ab3SNickeau *
1321913ab3SNickeau */
1421913ab3SNickeauclass  action_plugin_combo_webcode extends DokuWiki_Action_Plugin
1521913ab3SNickeau{
1621913ab3SNickeau
1721913ab3SNickeau    const CALL_ID = "webcode";
18531e725cSNickeau    const MARKI_PARAM = "marki";
19531e725cSNickeau
2021913ab3SNickeau
2121913ab3SNickeau    function register(Doku_Event_Handler $controller)
2221913ab3SNickeau    {
23*28451e1eSgerardnico        /**
24*28451e1eSgerardnico         * To serve fragment
25*28451e1eSgerardnico         */
2621913ab3SNickeau        $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, '_ajax_call');
27*28451e1eSgerardnico
28*28451e1eSgerardnico        /**
29*28451e1eSgerardnico         * To enforce security
30*28451e1eSgerardnico         */
31*28451e1eSgerardnico        $controller->register_hook('COMMON_WIKIPAGE_SAVE', 'BEFORE', $this, '_enforceSecurity');
32*28451e1eSgerardnico
3321913ab3SNickeau    }
3421913ab3SNickeau
3521913ab3SNickeau    /**
3621913ab3SNickeau     * handle ajax requests
3721913ab3SNickeau     * @param $event Doku_Event
3821913ab3SNickeau     *
3921913ab3SNickeau     * {@link html_show()}
4021913ab3SNickeau     *
4121913ab3SNickeau     * https://www.dokuwiki.org/devel:plugin_programming_tips#handle_json_ajax_request
4221913ab3SNickeau     *
4321913ab3SNickeau     * CSRF checks are only for logged in users
4421913ab3SNickeau     * This is public ({@link getSecurityToken()}
4521913ab3SNickeau     */
4621913ab3SNickeau    function _ajax_call(&$event)
4721913ab3SNickeau    {
4821913ab3SNickeau
4921913ab3SNickeau        if ($event->data !== self::CALL_ID) {
5021913ab3SNickeau            return;
5121913ab3SNickeau        }
5221913ab3SNickeau        //no other ajax call handlers needed
5321913ab3SNickeau        $event->stopPropagation();
5421913ab3SNickeau        $event->preventDefault();
5521913ab3SNickeau
5621913ab3SNickeau
5721913ab3SNickeau        global $INPUT;
58531e725cSNickeau        $marki = $INPUT->str(self::MARKI_PARAM);
5921913ab3SNickeau        $title = $INPUT->str('title') ?: "ComboStrap WebCode - Dokuwiki Renderer";
6021913ab3SNickeau
6121913ab3SNickeau
6221913ab3SNickeau        header('Content-Type: text/html; charset=utf-8');
6321913ab3SNickeau
6421913ab3SNickeau        /**
6521913ab3SNickeau         * Conf
6621913ab3SNickeau         */
6721913ab3SNickeau        PluginUtility::setConf(action_plugin_combo_css::CONF_DISABLE_DOKUWIKI_STYLESHEET, true);
6821913ab3SNickeau
6921913ab3SNickeau        /**
7021913ab3SNickeau         * Main content happens before the headers
7121913ab3SNickeau         * to set the headers right
7221913ab3SNickeau         */
73531e725cSNickeau        global $conf;
74531e725cSNickeau        $conf["renderer_xhtml"] = "xhtml";
75c3437056SNickeau
76c3437056SNickeau        global $ID;
77c3437056SNickeau        $keep = $ID;
78c3437056SNickeau        try {
79c3437056SNickeau            $ID = "ajax_webcode_" . md5($marki);
80531e725cSNickeau            $mainContent = p_render('xhtml', p_get_instructions($marki), $info);
8121913ab3SNickeau
8221913ab3SNickeau            /**
8321913ab3SNickeau             * Html
8421913ab3SNickeau             */
8521913ab3SNickeau            $htmlBeforeHeads = '<!DOCTYPE html>' . DOKU_LF;
86*28451e1eSgerardnico            $htmlBeforeHeads .= '<html lang="en">' . DOKU_LF;
8721913ab3SNickeau            $htmlBeforeHeads .= '<head>' . DOKU_LF;
8821913ab3SNickeau            $htmlBeforeHeads .= "  <title>$title</title>" . DOKU_LF;
8921913ab3SNickeau            // we echo because the tpl function just flush
9021913ab3SNickeau            echo $htmlBeforeHeads;
9121913ab3SNickeau
9221913ab3SNickeau            if (Site::isStrapTemplate()) {
9321913ab3SNickeau
9421913ab3SNickeau                /**
9521913ab3SNickeau                 * The strap header function
9621913ab3SNickeau                 */
974cadd4f8SNickeau                try {
984cadd4f8SNickeau                    Site::loadStrapUtilityTemplateIfPresentAndSameVersion();
9921913ab3SNickeau                    TplUtility::registerHeaderHandler();
1004cadd4f8SNickeau                } catch (ExceptionCombo $e) {
1014cadd4f8SNickeau                    \ComboStrap\LogUtility::log2file("Error while registering the header handler on webcode ajax call. Error: {$e->getMessage()}");
10221913ab3SNickeau                }
1034cadd4f8SNickeau
104531e725cSNickeau            }
105531e725cSNickeau
10621913ab3SNickeau            /**
10721913ab3SNickeau             * To delete the not needed headers for an export
10821913ab3SNickeau             * such as manifest, alternate, ...
10921913ab3SNickeau             */
11021913ab3SNickeau            global $EVENT_HANDLER;
11121913ab3SNickeau            $EVENT_HANDLER->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, '_delete_not_needed_headers');
11221913ab3SNickeau
11321913ab3SNickeau            /**
11421913ab3SNickeau             * meta headers
11521913ab3SNickeau             */
11621913ab3SNickeau            tpl_metaheaders();
11721913ab3SNickeau
11821913ab3SNickeau
11921913ab3SNickeau            $htmlAfterHeads = '</head>' . DOKU_LF;
12021913ab3SNickeau            $htmlAfterHeads .= '<body>' . DOKU_LF;
12121913ab3SNickeau            $htmlAfterHeads .= $mainContent . DOKU_LF;
12221913ab3SNickeau            $htmlAfterHeads .= '</body>' . DOKU_LF;
12321913ab3SNickeau            $htmlAfterHeads .= '</html>' . DOKU_LF;
12421913ab3SNickeau            echo $htmlAfterHeads;
12521913ab3SNickeau            http_response_code(200);
12621913ab3SNickeau
127c3437056SNickeau        } finally {
128c3437056SNickeau            $ID = $keep;
129c3437056SNickeau        }
130c3437056SNickeau
13121913ab3SNickeau    }
13221913ab3SNickeau
133531e725cSNickeau    /**
134531e725cSNickeau     * Dynamically called in the previous function
135531e725cSNickeau     * to delete the head
136*28451e1eSgerardnico     * * @param $event Doku_Event
137531e725cSNickeau     */
138*28451e1eSgerardnico    public function _delete_not_needed_headers(Doku_Event &$event)
13921913ab3SNickeau    {
14021913ab3SNickeau        $data = &$event->data;
14121913ab3SNickeau
14221913ab3SNickeau        foreach ($data as $tag => &$heads) {
14321913ab3SNickeau            switch ($tag) {
14421913ab3SNickeau                case "link":
14521913ab3SNickeau                    $deletedRel = ["manifest", "search", "start", "alternate", "contents"];
14621913ab3SNickeau                    foreach ($heads as $id => $headAttributes) {
14721913ab3SNickeau                        if (isset($headAttributes['rel'])) {
14821913ab3SNickeau                            $rel = $headAttributes['rel'];
14921913ab3SNickeau                            if (in_array($rel, $deletedRel)) {
15021913ab3SNickeau                                unset($heads[$id]);
15121913ab3SNickeau                            }
15221913ab3SNickeau                        }
15321913ab3SNickeau                    }
15421913ab3SNickeau                    break;
15521913ab3SNickeau                case "meta":
15621913ab3SNickeau                    $deletedMeta = ["robots"];
15721913ab3SNickeau                    foreach ($heads as $id => $headAttributes) {
15821913ab3SNickeau                        if (isset($headAttributes['name'])) {
15921913ab3SNickeau                            $rel = $headAttributes['name'];
16021913ab3SNickeau                            if (in_array($rel, $deletedMeta)) {
16121913ab3SNickeau                                unset($heads[$id]);
16221913ab3SNickeau                            }
16321913ab3SNickeau                        }
16421913ab3SNickeau                    }
16521913ab3SNickeau                    break;
16621913ab3SNickeau                case "script":
16721913ab3SNickeau                    foreach ($heads as $id => $headAttributes) {
16821913ab3SNickeau                        if (isset($headAttributes['src'])) {
16921913ab3SNickeau                            $src = $headAttributes['src'];
17021913ab3SNickeau                            if (strpos($src, "lib/exe/js.php") !== false) {
17121913ab3SNickeau                                unset($heads[$id]);
17221913ab3SNickeau                            }
17321913ab3SNickeau                        }
17421913ab3SNickeau                    }
17521913ab3SNickeau            }
17621913ab3SNickeau        }
17721913ab3SNickeau    }
17821913ab3SNickeau
179*28451e1eSgerardnico    /**
180*28451e1eSgerardnico     * @param $event Doku_Event https://www.dokuwiki.org/devel:event:common_wikipage_save
181*28451e1eSgerardnico     * @return void
182*28451e1eSgerardnico     */
183*28451e1eSgerardnico    function _enforceSecurity(Doku_Event &$event)
184*28451e1eSgerardnico    {
185*28451e1eSgerardnico
186*28451e1eSgerardnico        $data = $event->data;
187*28451e1eSgerardnico        $text = $data["newContent"];
188*28451e1eSgerardnico        $pattern = PluginUtility::getContainerTagPattern(syntax_plugin_combo_webcode::TAG);
189*28451e1eSgerardnico        $result = preg_match("/" . $pattern . "/ms", $text);
190*28451e1eSgerardnico        if ($result === 0) {
191*28451e1eSgerardnico            return;
192*28451e1eSgerardnico        }
193*28451e1eSgerardnico
194*28451e1eSgerardnico        $isAdmin = Identity::isAdmin();
195*28451e1eSgerardnico        $isMember = Identity::isMember("@" . action_plugin_combo_svg::CONF_SVG_UPLOAD_GROUP_NAME);
196*28451e1eSgerardnico        if (!($isAdmin || $isMember)) {
197*28451e1eSgerardnico            $event->preventDefault();
198*28451e1eSgerardnico        }
199*28451e1eSgerardnico
200*28451e1eSgerardnico    }
20121913ab3SNickeau
20221913ab3SNickeau}
203