1<?php 2 3use ComboStrap\ExceptionCombo; 4use ComboStrap\PluginUtility; 5use ComboStrap\Site; 6use ComboStrap\TplUtility; 7 8if (!defined('DOKU_INC')) die(); 9 10/** 11 * 12 */ 13class action_plugin_combo_webcode extends DokuWiki_Action_Plugin 14{ 15 16 const CALL_ID = "webcode"; 17 const MARKI_PARAM = "marki"; 18 19 20 function register(Doku_Event_Handler $controller) 21 { 22 $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, '_ajax_call'); 23 } 24 25 /** 26 * handle ajax requests 27 * @param $event Doku_Event 28 * 29 * {@link html_show()} 30 * 31 * https://www.dokuwiki.org/devel:plugin_programming_tips#handle_json_ajax_request 32 * 33 * CSRF checks are only for logged in users 34 * This is public ({@link getSecurityToken()} 35 */ 36 function _ajax_call(&$event) 37 { 38 39 if ($event->data !== self::CALL_ID) { 40 return; 41 } 42 //no other ajax call handlers needed 43 $event->stopPropagation(); 44 $event->preventDefault(); 45 46 47 global $INPUT; 48 $marki = $INPUT->str(self::MARKI_PARAM); 49 $title = $INPUT->str('title') ?: "ComboStrap WebCode - Dokuwiki Renderer"; 50 51 52 header('Content-Type: text/html; charset=utf-8'); 53 54 /** 55 * Conf 56 */ 57 PluginUtility::setConf(action_plugin_combo_css::CONF_DISABLE_DOKUWIKI_STYLESHEET, true); 58 59 /** 60 * Main content happens before the headers 61 * to set the headers right 62 */ 63 global $conf; 64 $conf["renderer_xhtml"] = "xhtml"; 65 66 global $ID; 67 $keep = $ID; 68 try { 69 $ID = "ajax_webcode_" . md5($marki); 70 $mainContent = p_render('xhtml', p_get_instructions($marki), $info); 71 72 /** 73 * Html 74 */ 75 $htmlBeforeHeads = '<!DOCTYPE html>' . DOKU_LF; 76 $htmlBeforeHeads .= '<html>' . DOKU_LF; 77 $htmlBeforeHeads .= '<head>' . DOKU_LF; 78 $htmlBeforeHeads .= " <title>$title</title>" . DOKU_LF; 79 // we echo because the tpl function just flush 80 echo $htmlBeforeHeads; 81 82 if (Site::isStrapTemplate()) { 83 84 /** 85 * The strap header function 86 */ 87 try { 88 Site::loadStrapUtilityTemplateIfPresentAndSameVersion(); 89 TplUtility::registerHeaderHandler(); 90 } catch (ExceptionCombo $e) { 91 \ComboStrap\LogUtility::log2file("Error while registering the header handler on webcode ajax call. Error: {$e->getMessage()}"); 92 } 93 94 } 95 96 /** 97 * To delete the not needed headers for an export 98 * such as manifest, alternate, ... 99 */ 100 global $EVENT_HANDLER; 101 $EVENT_HANDLER->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, '_delete_not_needed_headers'); 102 103 /** 104 * meta headers 105 */ 106 tpl_metaheaders(); 107 108 109 $htmlAfterHeads = '</head>' . DOKU_LF; 110 $htmlAfterHeads .= '<body>' . DOKU_LF; 111 $htmlAfterHeads .= $mainContent . DOKU_LF; 112 $htmlAfterHeads .= '</body>' . DOKU_LF; 113 $htmlAfterHeads .= '</html>' . DOKU_LF; 114 echo $htmlAfterHeads; 115 http_response_code(200); 116 117 } finally { 118 $ID = $keep; 119 } 120 121 } 122 123 /** 124 * Dynamically called in the previous function 125 * to delete the head 126 * @param $event 127 */ 128 public function _delete_not_needed_headers(&$event) 129 { 130 $data = &$event->data; 131 132 foreach ($data as $tag => &$heads) { 133 switch ($tag) { 134 case "link": 135 $deletedRel = ["manifest", "search", "start", "alternate", "contents"]; 136 foreach ($heads as $id => $headAttributes) { 137 if (isset($headAttributes['rel'])) { 138 $rel = $headAttributes['rel']; 139 if (in_array($rel, $deletedRel)) { 140 unset($heads[$id]); 141 } 142 } 143 } 144 break; 145 case "meta": 146 $deletedMeta = ["robots"]; 147 foreach ($heads as $id => $headAttributes) { 148 if (isset($headAttributes['name'])) { 149 $rel = $headAttributes['name']; 150 if (in_array($rel, $deletedMeta)) { 151 unset($heads[$id]); 152 } 153 } 154 } 155 break; 156 case "script": 157 foreach ($heads as $id => $headAttributes) { 158 if (isset($headAttributes['src'])) { 159 $src = $headAttributes['src']; 160 if (strpos($src, "lib/exe/js.php") !== false) { 161 unset($heads[$id]); 162 } 163 } 164 } 165 } 166 } 167 } 168 169 170} 171