1<?php 2/** 3 * DokuWiki Plugin highlight2wiki (Action Component) 4 * 5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 6 * @author dodotori <dodotori@localhost> 7 CRC64 function adapted from https://gist.github.com/hightemp/4da5ac39b8d57fcd7e7988b90a48017d 8 several function adapted from stackoverflow 9 10bookmarklet: 11javascript:Q=document.selection?document.selection.createRange().text:document.getSelection(); void(window.open(%27https://yourwebsite.com/dokuwiki/doku.php?do=highlight2wiki&te=%27+encodeURIComponent(Q)+%27&ur=%27+ encodeURIComponent(location.href)+%27%27,%27dokuwikiadd%27,%27scrollbars=yes,resizable=yes,toolbars=yes,status=yes%27)); 12 13 14 */ 15 16class action_plugin_highlight2wiki extends \dokuwiki\Extension\ActionPlugin 17{ 18 /** @inheritDoc */ 19 public function register(Doku_Event_Handler $controller) 20 { 21 // $controller->register_hook('TOOLBAR_DEFINE', 'AFTER', $this, 'handle_toolbar_define',array()); 22 $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this,'_hookjs'); 23 $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'allowMyAction'); 24 $controller->register_hook('TPL_ACT_UNKNOWN', 'BEFORE', $this, 'performMyAction'); 25 26 } 27 28 /** 29 * FIXME Event handler for 30 * 31 * @param Doku_Event $event event object by reference 32 * @param mixed $param optional parameter passed when event was registered 33 * @return void 34 */ 35 public function _hookjs(Doku_Event $event, $param) { 36 $event->data['script'][] = array( 37 'type' => 'text/javascript', 38 'charset' => 'utf-8', 39 '_data' => '', 40 'src' => 'https://cdnjs.cloudflare.com/ajax/libs/mark.js/8.11.1/mark.min.js'); // Mark.Js library included 41 //'src' => DOKU_BASE.'lib/plugins/highlight2wiki/script.js'); 42 } 43 public function allowMyAction(Doku_Event $event, $param) { 44 if($event->data != 'highlight2wiki') return; 45 $event->preventDefault(); 46 47 } 48 49 public function performMyAction(Doku_Event $event, $param) { 50 if($event->data != 'highlight2wiki') return; 51 $event->preventDefault(); 52 global $ACT, $JSINFO, $ID, $INPUT, $auth, $TPL, $INFO; 53 54 //LOGIN NEEDED ?8 //NOT LOGGED IN ? -> FORCE LOGIN 55 if( $INFO['userinfo']== null ) { 56 header("Location: ?do=login"); 57 die('<a href="?do=login">LOGIN</a>'); 58 } 59 60 61 62 $timestamp = date("Y:m:d:H:i:s"); 63 //$title=$_GET['ti']; // things to log : title 64 //$titlestring = preg_replace('/%u([0-9A-F]+)/', '&#x$1;', $title); // convert the unicode dont need title parameter anymore 65 //$titlestring = html_entity_decode($titlestring, ENT_COMPAT, 'UTF-8'); 66 $url=$_GET['ur']; 67 //$urlkey = preg_replace( "#^[^:/.]*[:/]+#i", "",$url ); 68 //$urlkey = urlencode($urlkey); //crc64($url); 69 //if (strlen($urlkey)>250){ 70 $urlkey = crc64($url); 71 //} 72 $yournamespace = $this->getConf('highlight_namespace'); 73 $allowed_tags = $this->getConf('allowed_tags'); 74 $allow_css = $this->getConf('allow_css'); 75 $allow_javascript = $this->getConf('allow_javascript'); 76 $title_as_pagename = $this->getConf('title_as_pagename'); 77 $targeturl= DOKU_BASE."doku.php?id=$yournamespace:$urlkey&do=edit"; 78 $highlightactionurl = DOKU_BASE."doku.php?do=highlight2wiki"; 79 $url_host = parse_url($url,PHP_URL_SCHEME)."://".parse_url($url, PHP_URL_HOST) ; 80 81 82 if(empty($url)){ 83 echo "<p>put your link here:</p>"; 84 echo '<input id="linktogo">'; 85 echo '<input type="button" onclick="location.href=\'?do=highlight2wiki&ur=\'+encodeURIComponent(getElementById(\'linktogo\').value);" value="Highlight2wiki" />'; 86 } 87 echo'<input type="button" value="DarkMode" class="unibutton" onpointerdown="HLdarkmode()">'; 88 echo '<script> 89 console.log("'.$url.'"); 90 console.log("'.$urlkey.'"); 91 console.log("'.$yournamespace.'"); 92 93 var url = "'.$url.'" 94 var urlkey = "'.$urlkey.'"; 95 var timestamp = "'.$timestamp.'"; 96 var targeturl = "'.$targeturl.'"; 97 var highlightactionurl ="'.$highlightactionurl.'"; 98 var url_host ="'.$url_host.'"; 99 100 </script>'; 101 102 103 104// From URL to get webpage contents. 105 106 function parseurl($newurl="") // to convert encode url 107{ 108 // $newurl = rawurlencode($newurl); 109 $a = array("%3A","%2F","%40","+"); 110 $b = array(":","/","@"," "); 111 $newurl = str_replace($a,$b,$newurl); 112 return $newurl; 113} 114 115$purl = parseurl($url); 116 117 118 119 if(!empty($url)){ 120if (function_exists('curl_init')) //check if curl function existed 121{ 122 $ch = curl_init(); 123 $agent = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36'; 124 curl_setopt($ch, CURLOPT_USERAGENT, $agent);// Return Page contents. 125 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 126 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); 127 curl_setopt($ch, CURLOPT_URL, $url); 128 curl_setopt($ch, CURLOPT_LOW_SPEED_LIMIT, 1); // cancel if below 1 byte/second 129 curl_setopt($ch, CURLOPT_LOW_SPEED_TIME, 30); // for a period of 30 seconds 130 $result1 = curl_exec($ch); 131 //grab URL and pass it to the variable. 132 // Initialize a CURL session. 133 //$result =file_get_contents($url); 134 135 $context2 = stream_context_create( 136 array( 137 "http" => array( 138 "header" => "User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36" 139 ), 140 "ssl"=>array( 141 "verify_peer"=>false, 142 "verify_peer_name"=>false,) 143 ) 144 ); 145 146 $result2 =file_get_contents($url, false, $context2); 147 //echo '<p>'.strlen($result1).'</p>'; 148 //echo '<p>'.strlen($result2).'</p>'; 149 if(strlen($result2)>strlen($result1)){ //check length of each result 150 $result = $result2; 151 }else{ 152 $result = $result1; 153 } 154} 155else 156{ 157 $context = stream_context_create( 158 array( 159 "http" => array( 160 "header" => "User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36" 161 ), 162 "ssl"=>array( 163 "verify_peer"=>false, 164 "verify_peer_name"=>false,) 165 ) 166 ); 167 $result =file_get_contents($url, false, $context); 168 echo '<p>file_get_contents</p>'; 169 170} 171} 172 173 174//$result2= file_get_contents($url); 175//if(strcmp($result, $result2)<"0"){ 176//$result = $result2; 177//} 178 179/* DOM parser stripper from https://stackoverflow.com/questions/8021543/extract-all-the-text-and-img-tags-from-html-in-php */ 180if($result!=""){ 181//preg_match('/lang=(["\'])?((?:.(?!\1|>))*.?)/',$result,$matchlang); 182$allowed_attributes = array('charset','lang','src','href'); 183 184$dom = new DOMDocument(); 185 186 187//$dom->loadHTML($result); 188@$dom->loadHTML(mb_convert_encoding($result, 'HTML-ENTITIES', 'UTF-8')); 189 190 191 192//mb_convert_encoding($data, 'HTML-ENTITIES', 'UTF-8') 193foreach($dom->getElementsByTagName('*') as $node) 194{ 195 foreach($node->attributes as $attribute) 196 { 197 if(is_iterable($attribute->name)){ 198 foreach($attribute->name as $AName){ 199 if(in_array($AName, $allowed_attributes)){ 200 continue; 201 }else{ 202 $node->removeAttributeNode($attribute); 203 } 204 205 } 206 } 207 //if (in_array($attribute->name, $allowed_attributes)) {continue;} 208 //$node->removeAttributeNode($attribute); 209 //removeAttribute('href') 210 } 211} 212 213if($allow_javascript==0){ //javascript_conf 214/*$html = preg_replace('/<\s*script.+?<\s*\/\s*script.*?>/si', ' ', $html ); */ 215foreach($dom->getElementsByTagName('script') as $node){$node->nodeValue="";} 216echo'<script>console.log("no js")</script>'; 217} 218 219if($allow_css==0){ //css conf 220/*$html = preg_replace('/<\s*style.+?<\s*\/\s*script.*?>/si', ' ', $html ); */ 221foreach($dom->getElementsByTagName('style') as $node){$node->nodeValue="";} 222echo'<script>console.log("no css")</script>'; 223} 224 225 226//echo '<meta lang="'.$matchlang[2].'"><html>'; 227echo '<meta Content-Type" content="text/html; charset="UTF-8">'; 228$titles = $dom->saveHTML($dom->getElementsByTagName('title')->item(0)); 229$html = $dom->saveHTML($dom->getElementsByTagname('body')->item(0)); 230 231if($allow_javascript==0){ 232$html = preg_replace('/<\s*script.+?<\s*\/\s*script.*?>/si', ' ', $html ); 233} 234$html=preg_replace("/<body[^>]+\>/ix", "", $html); 235$html = str_replace("<body>", "", $html); 236$html = str_replace("</body>", "", $html); 237 238echo'<div id="wanttext">'; 239echo $titles; 240echo $html; 241} 242 243echo "</div>"; 244 245// add onload function 246echo' <script> </script>'; 247 248 249 250 251 252 253/* change the target page name to title+ crc64 code */ 254if($title_as_pagename ==1){ 255$titles2=RemoveSpecialChar(Strip_tags($titles)); 256if (strlen(utf8_encode($titles2))>140){ //check the title length if longer than 150 257$titles2 = substr(utf8_encode($titles2),0,140); 258$titles2 = utf8_decode($titles2); 259} 260$titles2 = $titles2."-".crc64($url); 261$targeturl= DOKU_BASE."doku.php?id=$yournamespace:$titles2&do=edit"; 262} 263/* dokuwiki editor iframe */ 264echo '<iframe src="'.$targeturl.'" id="edtop" width="100%" height="800 px" onload="loadH2WFunc()"></iframe>'; 265 266 echo'<div id="ednavbar"> 267 <!--Button to invoke the function to get the selected text--> 268 <!--<input type="button" value="Highlight" class="unibutton" onpointerdown ="getSelectedText()">--> 269 <!--<input type="button" value="Load" class="unibutton" onpointerdown ="loadhighlight();">--> 270 <input type="button" value="✎Mark" class="unibutton" onpointerdown="markjs()"> 271 <input type="button" value="⌛Load" class="unibutton" onpointerdown="loadmarkjs()" > 272 <input type = "button" value="〒Tag" class="unibutton" onpointerdown="edittag();"> 273 <input type="button" value="✍Learn" class="unibutton" onpointerdown="loadmarkjsfr();"> 274 <input type="button" class="unibutton" value="Up" onpointerdown="jQuery(\'html, body\').animate({scrollTop:0}, \'300\')").scrollIntoView");"> 275 <input type="button" class="unibutton" value="Dn" onpointerdown="document.getElementById(\'edtop\').scrollIntoView();"> 276 <input type="button" class="unibutton" value="☯Dark" onpointerdown="HLdarkmode()" > 277 </div>'; 278 279 280echo ' 281 <!--Form to show the selected text as output--> 282 <form align="right" 283 <input type="button" value="Go to Top " onclick="document.getElementById(\'wanttext\').scrollIntoView();" > 284 <p> </p> 285 286 </form>'; 287 288 289 290 291 // <form name="testform" hidden="hidden" > 292 // <textarea name="selectedtext" 293 //rows="3" 294 //cols="20" 295 // hidden="hidden"></textarea> 296 // </form> 297 298 299 300} //end of performMyAction 301 302} // end of class 303 304 305 306function crc64Table() //CRC64 hasing for encoding 307{ 308 $crc64tab = []; 309 310 // ECMA polynomial 311 $poly64rev = (0xC96C5795 << 32) | 0xD7870F42; 312 313 // ISO polynomial 314 // $poly64rev = (0xD8 << 56); 315 316 for ($i = 0; $i < 256; $i++) 317 { 318 for ($part = $i, $bit = 0; $bit < 8; $bit++) { 319 if ($part & 1) { 320 $part = (($part >> 1) & ~(0x8 << 60)) ^ $poly64rev; 321 } else { 322 $part = ($part >> 1) & ~(0x8 << 60); 323 } 324 } 325 326 $crc64tab[$i] = $part; 327 } 328 329 return $crc64tab; 330} 331 332 333 334//https://www.php.net/manual/en/function.str-replace.php#100871 335 336 337 338 339 340 341/** 342* @param string $string 343* @param string $format 344* @return mixed 345* 346* Formats: 347* crc64('php'); // afe4e823e7cef190 348* crc64('php', '0x%x'); // 0xafe4e823e7cef190 349* crc64('php', '0x%X'); // 0xAFE4E823E7CEF190 350* crc64('php', '%d'); // -5772233581471534704 signed int 351* crc64('php', '%u'); // 12674510492238016912 unsigned int 352*/ 353function crc64($string, $format = '%x') 354{ 355 static $crc64tab; 356 357 if ($crc64tab === null) { 358 $crc64tab = crc64Table(); 359 } 360 361 $crc = 0; 362 363 for ($i = 0; $i < strlen($string); $i++) { 364 $crc = $crc64tab[($crc ^ ord($string[$i])) & 0xff] ^ (($crc >> 8) & ~(0xff << 56)); 365 } 366 367 return sprintf($format, $crc); 368} 369 370 371 372 373//check itf-8 //floern.com/; 374 375function is_utf8($str) { 376 $strlen = strlen($str); 377 for ($i = 0; $i < $strlen; $i++) { 378 $ord = ord($str[$i]); 379 if ($ord < 0x80) continue; // 0bbbbbbb 380 elseif (($ord & 0xE0) === 0xC0 && $ord > 0xC1) $n = 1; // 110bbbbb (exkl C0-C1) 381 elseif (($ord & 0xF0) === 0xE0) $n = 2; // 1110bbbb 382 elseif (($ord & 0xF8) === 0xF0 && $ord < 0xF5) $n = 3; // 11110bbb (exkl F5-FF) 383 else return false; // invalid UTF-8-Zeichen 384 for ($c=0; $c<$n; $c++) // $n following bytes? // 10bbbbbb 385 if (++$i === $strlen || (ord($str[$i]) & 0xC0) !== 0x80) 386 return false; // invalid UTF-8 char 387 } 388 return true; // didn't find any invalid characters 389} 390 391 392 function RemoveSpecialChar($str) { 393// Using str_replace() function 394// to replace the word 395$res = str_replace( array( '\'', '"', 396',' , ';', '<', '>','&',':','/' ), '', $str); 397return $res; 398 } 399